ソースを参照

Add option to specific value length

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 年 前
コミット
c2a8bd9881

+ 6 - 2
docs/running.rst

@@ -32,8 +32,12 @@ Options:
   This takes one argument, which can either be ``solana``, ``substrate``, or ``ewasm``. The target
   must be specified.
 
-\\-\\-address\-length *length-in-bytes*
-  Change the default address length on Substrate. By default, Substate uses an address of 32 bytes. This option
+\\-\\-address\\-length *length-in-bytes*
+  Change the default address length on Substrate. By default, Substate uses an address type of 32 bytes. This option
+  is ignored for any other target.
+
+\\-\\-value\\-length *length-in-bytes*
+  Change the default value length on Substrate. By default, Substate uses an value type of 16 bytes. This option
   is ignored for any other target.
 
 \\-\\-doc

+ 29 - 1
src/bin/solang.rs

@@ -75,6 +75,13 @@ fn main() {
                 .takes_value(true)
                 .default_value("32"),
         )
+        .arg(
+            Arg::with_name("VALUE_LENGTH")
+                .help("Value length on Substrate")
+                .long("value-length")
+                .takes_value(true)
+                .default_value("16"),
+        )
         .arg(
             Arg::with_name("STD-JSON")
                 .help("mimic solidity json output on stdout")
@@ -164,9 +171,22 @@ fn main() {
         }
     };
 
+    let value_length = matches.value_of("VALUE_LENGTH").unwrap();
+
+    let value_length = match value_length.parse() {
+        Ok(len) if (4..1024).contains(&len) => len,
+        _ => {
+            eprintln!("error: value length ‘{}’ is not valid", value_length);
+            std::process::exit(1);
+        }
+    };
+
     let target = match matches.value_of("TARGET") {
         Some("solana") => solang::Target::Solana,
-        Some("substrate") => solang::Target::Substrate { address_length },
+        Some("substrate") => solang::Target::Substrate {
+            address_length,
+            value_length,
+        },
         Some("ewasm") => solang::Target::Ewasm,
         _ => unreachable!(),
     };
@@ -179,6 +199,14 @@ fn main() {
         std::process::exit(1);
     }
 
+    if !target.is_substrate() && matches.occurrences_of("VALUE_LENGTH") > 0 {
+        eprintln!(
+            "error: value length cannot be modified for target ‘{}’",
+            target
+        );
+        std::process::exit(1);
+    }
+
     if matches.is_present("LANGUAGESERVER") {
         languageserver::start_server(target);
     }

+ 4 - 1
src/codegen/strength_reduce.rs

@@ -1772,7 +1772,10 @@ fn test_highest_bit() {
 
 #[test]
 fn expresson_known_bits() {
-    let ns = Namespace::new(crate::Target::Substrate { address_length: 32 });
+    let ns = Namespace::new(crate::Target::Substrate {
+        address_length: 32,
+        value_length: 16,
+    });
     let loc = crate::parser::pt::Loc(0, 0, 0);
 
     let mut vars: Variables = HashMap::new();

+ 10 - 2
src/emit/substrate.rs

@@ -3406,7 +3406,11 @@ impl<'a> TargetRuntime<'a> for SubstrateTarget {
                 binary.module.get_function("seal_instantiate").unwrap(),
                 &[
                     codehash.into(),
-                    binary.context.i32_type().const_int(32, false).into(),
+                    binary
+                        .context
+                        .i32_type()
+                        .const_int(ns.address_length as u64, false)
+                        .into(),
                     gas.into(),
                     binary
                         .builder
@@ -3416,7 +3420,11 @@ impl<'a> TargetRuntime<'a> for SubstrateTarget {
                             "value_transfer",
                         )
                         .into(),
-                    binary.context.i32_type().const_int(16, false).into(),
+                    binary
+                        .context
+                        .i32_type()
+                        .const_int(ns.value_length as u64, false)
+                        .into(),
                     input.into(),
                     input_len.into(),
                     address.into(),

+ 4 - 1
src/lib.rs

@@ -23,7 +23,10 @@ pub enum Target {
     /// Solana, see <https://solana.com/>
     Solana,
     /// Parity Substrate, see <https://substrate.dev/>
-    Substrate { address_length: usize },
+    Substrate {
+        address_length: usize,
+        value_length: usize,
+    },
     /// Ethereum ewasm, see <https://github.com/ewasm/design>
     Ewasm,
 }

+ 41 - 8
src/sema/builtin.rs

@@ -87,7 +87,13 @@ static BUILTIN_FUNCTIONS: [Prototype; 24] = [
         name: "selfdestruct",
         args: &[Type::Address(true)],
         ret: &[Type::Unreachable],
-        target: &[Target::Ewasm, Target::Substrate { address_length: 0 }],
+        target: &[
+            Target::Ewasm,
+            Target::Substrate {
+                address_length: 32,
+                value_length: 16,
+            },
+        ],
         doc: "Destroys current account and deposits any remaining balance to address",
         constant: false,
     },
@@ -127,7 +133,10 @@ static BUILTIN_FUNCTIONS: [Prototype; 24] = [
         name: "blake2_128",
         args: &[Type::DynamicBytes],
         ret: &[Type::Bytes(16)],
-        target: &[Target::Substrate { address_length: 0 }],
+        target: &[Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        }],
         doc: "Calculates blake2-128 hash",
         constant: true,
     },
@@ -137,7 +146,10 @@ static BUILTIN_FUNCTIONS: [Prototype; 24] = [
         name: "blake2_256",
         args: &[Type::DynamicBytes],
         ret: &[Type::Bytes(32)],
-        target: &[Target::Substrate { address_length: 0 }],
+        target: &[Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        }],
         doc: "Calculates blake2-256 hash",
         constant: true,
     },
@@ -147,7 +159,13 @@ static BUILTIN_FUNCTIONS: [Prototype; 24] = [
         name: "gasleft",
         args: &[],
         ret: &[Type::Uint(64)],
-        target: &[Target::Substrate { address_length: 0 }, Target::Ewasm],
+        target: &[
+            Target::Substrate {
+                address_length: 32,
+                value_length: 16,
+            },
+            Target::Ewasm,
+        ],
         doc: "Return remaing gas left in current call",
         constant: false,
     },
@@ -167,7 +185,10 @@ static BUILTIN_FUNCTIONS: [Prototype; 24] = [
         name: "random",
         args: &[Type::DynamicBytes],
         ret: &[Type::Bytes(32)],
-        target: &[Target::Substrate { address_length: 0 }],
+        target: &[Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        }],
         doc: "Returns deterministic random bytes",
         constant: false,
     },
@@ -337,7 +358,10 @@ static BUILTIN_VARIABLE: [Prototype; 14] = [
         name: "tombstone_deposit",
         args: &[],
         ret: &[Type::Value],
-        target: &[Target::Substrate { address_length: 0 }],
+        target: &[Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        }],
         doc: "Deposit required for a tombstone",
         constant: false,
     },
@@ -347,7 +371,10 @@ static BUILTIN_VARIABLE: [Prototype; 14] = [
         name: "minimum_balance",
         args: &[],
         ret: &[Type::Value],
-        target: &[Target::Substrate { address_length: 0 }],
+        target: &[Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        }],
         doc: "Minimum balance required for an account",
         constant: false,
     },
@@ -397,7 +424,13 @@ static BUILTIN_VARIABLE: [Prototype; 14] = [
         name: "gasprice",
         args: &[],
         ret: &[Type::Value],
-        target: &[Target::Substrate { address_length: 0 }, Target::Ewasm],
+        target: &[
+            Target::Substrate {
+                address_length: 32,
+                value_length: 16,
+            },
+            Target::Ewasm,
+        ],
         doc: "gas price for one gas unit",
         constant: false,
     },

+ 7 - 10
src/sema/mod.rs

@@ -313,16 +313,13 @@ fn resolve_pragma(name: &pt::Identifier, value: &pt::StringLiteral, ns: &mut ast
 impl ast::Namespace {
     /// Create a namespace and populate with the parameters for the target
     pub fn new(target: Target) -> Self {
-        let address_length = match target {
-            Target::Ewasm => 20,
-            Target::Substrate { address_length } => address_length,
-            Target::Solana => 32,
-        };
-
-        let value_length = if target == Target::Solana {
-            8 // lamports is u64
-        } else {
-            16 // value is 128 bits
+        let (address_length, value_length) = match target {
+            Target::Ewasm => (20, 16),
+            Target::Substrate {
+                address_length,
+                value_length,
+            } => (address_length, value_length),
+            Target::Solana => (32, 8),
         };
 
         ast::Namespace {

+ 8 - 2
tests/substrate.rs

@@ -1194,7 +1194,10 @@ pub fn build_solidity(src: &'static str) -> TestRuntime {
         "test.sol",
         &mut cache,
         inkwell::OptimizationLevel::Default,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
         false,
     );
 
@@ -1231,7 +1234,10 @@ pub fn build_solidity_with_overflow_check(src: &'static str) -> TestRuntime {
         "test.sol",
         &mut cache,
         inkwell::OptimizationLevel::Default,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
         true,
     );
 

+ 136 - 34
tests/substrate_tests/arrays.rs

@@ -22,7 +22,10 @@ fn missing_array_index() {
                     return bar[];
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -39,7 +42,10 @@ fn missing_array_index() {
                     return bar[0];
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -226,7 +232,10 @@ fn data_locations() {
             function bar(uint storage) public returns () {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -240,7 +249,10 @@ fn data_locations() {
             function bar(uint calldata x) public returns () {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -255,7 +267,10 @@ fn data_locations() {
             function bar(foo2 memory x) public returns () {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -270,7 +285,10 @@ fn data_locations() {
             function bar(foo2 x) public returns (uint calldata) {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -285,7 +303,10 @@ fn data_locations() {
             function bar(foo2 x) public returns (bool calldata) {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -300,7 +321,10 @@ fn data_locations() {
             function bar(foo2 x) public returns (int storage) {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -315,7 +339,10 @@ fn data_locations() {
             function bar(int[10] storage x) public returns (int) {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -330,7 +357,10 @@ fn data_locations() {
             function bar() public returns (int[10] storage x) {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -345,7 +375,10 @@ fn data_locations() {
             function bar() public returns (foo2[10] storage x) {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -509,7 +542,10 @@ fn array_dimensions() {
         contract foo {
             bool[10 - 10] x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "zero size array not permitted");
@@ -519,7 +555,10 @@ fn array_dimensions() {
         contract foo {
             bool[-10 + 10] x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -532,7 +571,10 @@ fn array_dimensions() {
         contract foo {
             bool[1 / 10] x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "zero size array not permitted");
@@ -543,7 +585,10 @@ fn array_dimensions() {
             enum e { e1, e2, e3 }
             e[1 / 0] x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "divide by zero");
@@ -556,7 +601,10 @@ fn array_dimensions() {
             }
             bar[1 % 0] x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "divide by zero");
@@ -790,7 +838,10 @@ fn memory_dynamic_array_new() {
                 assert(a.length == 5);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -807,7 +858,10 @@ fn memory_dynamic_array_new() {
                 assert(a.length == 5);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -824,7 +878,10 @@ fn memory_dynamic_array_new() {
                 assert(a.length == 5);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -841,7 +898,10 @@ fn memory_dynamic_array_new() {
                 assert(a.length == 5);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -858,7 +918,10 @@ fn memory_dynamic_array_new() {
                 assert(a.length == 5);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -905,7 +968,10 @@ fn memory_dynamic_array_deref() {
                 a[-1] = 5;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -923,7 +989,10 @@ fn memory_dynamic_array_deref() {
                 a[i] = 5;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1098,7 +1167,10 @@ fn dynamic_array_push() {
                 bar.push(102, 20);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1228,7 +1300,10 @@ fn dynamic_array_pop() {
                 bar.pop(102);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1376,7 +1451,10 @@ fn storage_dynamic_array_push() {
                 bar.push(102, 20);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1393,7 +1471,10 @@ fn storage_dynamic_array_push() {
                 bar.push(102);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1459,7 +1540,10 @@ fn storage_dynamic_array_push() {
                 s storage n = bar.push(s(-1, false));
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1480,7 +1564,10 @@ fn storage_dynamic_array_pop() {
                 bar.pop(102);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1497,7 +1584,10 @@ fn storage_dynamic_array_pop() {
                 bar.pop();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1582,7 +1672,10 @@ fn storage_dynamic_array_pop() {
                 s storage x = bar.pop();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1602,7 +1695,10 @@ fn storage_delete() {
                 delete 102;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1619,7 +1715,10 @@ fn storage_delete() {
                 int32 x = delete bar;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -2015,7 +2114,10 @@ fn lucas() {
         }
     }
     "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);

+ 108 - 27
tests/substrate_tests/builtins.rs

@@ -13,7 +13,10 @@ fn abi_decode() {
                 (int a) = abi.decode(hex"00", feh);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "type ‘feh’ not found");
@@ -25,7 +28,10 @@ fn abi_decode() {
                 (int a) = abi.decode(hex"00", (int storage));
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -40,7 +46,10 @@ fn abi_decode() {
                 (int a) = abi.decode(hex"00", (int feh));
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -55,7 +64,10 @@ fn abi_decode() {
                 (int a) = abi.decode(hex"00", (int,));
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "missing type");
@@ -67,7 +79,10 @@ fn abi_decode() {
                 (int a) = abi.decode(hex"00", (int,mapping(uint[] => address)));
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -198,7 +213,10 @@ fn abi_encode_with_selector() {
                 bytes x = abi.encodeWithSelector();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -244,7 +262,10 @@ fn abi_encode_with_signature() {
                 bytes x = abi.encodeWithSignature();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -292,7 +313,10 @@ fn call() {
                 x.delegatecall(hex"1222");
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -309,7 +333,10 @@ fn call() {
                 x.staticcall(hex"1222");
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -332,7 +359,10 @@ fn call() {
                 print("Baa!");
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -355,7 +385,10 @@ fn call() {
                 print("Baa!");
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -496,7 +529,10 @@ fn block() {
                 assert(b == 14_250_083_331_950_119_597);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -526,7 +562,10 @@ fn block() {
                 assert(b == 14_250_083_331_950_119_597);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -556,7 +595,10 @@ fn block() {
                 assert(b == 93_603_701_976_053);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -586,7 +628,10 @@ fn block() {
                 assert(b == 93_603_701_976_053);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -603,7 +648,10 @@ fn block() {
                 assert(b == 93_603_701_976_053);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -620,7 +668,10 @@ fn block() {
                 assert(b == 93_603_701_976_053);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -637,7 +688,10 @@ fn block() {
                 assert(b == 93_603_701_976_053);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -681,7 +735,10 @@ fn tx() {
                 int128 b = tx.gasprice;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -696,7 +753,10 @@ fn tx() {
                 int128 b = tx.gasprice(4-3);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -713,7 +773,10 @@ fn tx() {
                 assert(b == 14_250_083_331_950_119_597);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -730,7 +793,10 @@ fn tx() {
                 assert(b == 93_603_701_976_053);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -764,7 +830,10 @@ fn msg() {
                 assert(b == 14_250_083_331_950_119_597);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -779,7 +848,10 @@ fn msg() {
                 return msg.value > v;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -830,7 +902,10 @@ fn functions() {
                 assert(b == 14_250_083_331_950_119_597);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -847,7 +922,10 @@ fn functions() {
                 assert(b == 14_250_083_331_950_119_597);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -862,7 +940,10 @@ fn functions() {
                 bytes32 b = blockhash(1);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 68 - 17
tests/substrate_tests/calls.rs

@@ -183,7 +183,10 @@ fn try_catch_external_calls() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -212,7 +215,10 @@ fn try_catch_external_calls() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -292,7 +298,10 @@ fn try_catch_external_calls() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -321,7 +330,10 @@ fn try_catch_external_calls() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "x is already declared");
@@ -349,7 +361,10 @@ fn try_catch_external_calls() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -380,7 +395,10 @@ fn try_catch_external_calls() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -524,7 +542,10 @@ fn try_catch_constructor() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -551,7 +572,10 @@ fn try_catch_constructor() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -655,7 +679,10 @@ fn try_catch_constructor() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -670,7 +697,10 @@ fn try_catch_constructor() {
                 x : 1
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -695,7 +725,10 @@ fn try_catch_constructor() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -724,7 +757,10 @@ fn try_catch_constructor() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "unexpected code block");
@@ -750,7 +786,10 @@ fn try_catch_constructor() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "unexpected code block");
@@ -966,7 +1005,10 @@ fn payable_functions() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -982,7 +1024,10 @@ fn payable_functions() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -998,7 +1043,10 @@ fn payable_functions() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1014,7 +1062,10 @@ fn payable_functions() {
             }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 84 - 21
tests/substrate_tests/contracts.rs

@@ -13,7 +13,10 @@ fn contract_name() {
         "contract test {
             function test() public {}
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -25,7 +28,10 @@ fn contract_name() {
         "contract test {
             enum test { a}
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -37,7 +43,10 @@ fn contract_name() {
         "contract test {
             bool test;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -49,7 +58,10 @@ fn contract_name() {
         "contract test {
             struct test { bool a; }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -63,7 +75,10 @@ fn contract_name() {
                 int test;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -76,7 +91,10 @@ fn contract_name() {
             function f(int test) public {
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -90,7 +108,10 @@ fn contract_name() {
                 return 0;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -112,7 +133,10 @@ fn contract_name() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -140,7 +164,10 @@ fn contract_name() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -168,7 +195,10 @@ fn contract_type() {
                 printer y = printer(x);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -183,7 +213,10 @@ fn contract_type() {
                 printer x = printer(address(102));
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -201,7 +234,10 @@ fn contract_type() {
                 address y = 102;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -222,7 +258,10 @@ fn contract_type() {
                 printer y = 102;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -237,7 +276,10 @@ fn contract_type() {
                 return new printer();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -252,7 +294,10 @@ fn contract_type() {
                 return new printer({});
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -277,7 +322,10 @@ fn external_call() {
                 return 1;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -299,7 +347,10 @@ fn external_call() {
                 return 1;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -328,7 +379,10 @@ fn external_call() {
                 return x * t;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -357,7 +411,10 @@ fn external_call() {
                 return x * t;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "duplicate argument name ‘a’");
@@ -529,7 +586,10 @@ fn creation_code() {
                 }
         }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -544,7 +604,10 @@ fn creation_code() {
                     bytes code = type(a).runtimeCode;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 23 - 5
tests/substrate_tests/enums.rs

@@ -92,7 +92,10 @@ fn test_cast_errors() {
                 return state.foo;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -107,7 +110,10 @@ fn test_cast_errors() {
                 return state.foo;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "enum ‘state’ has no fields");
@@ -119,7 +125,10 @@ fn test_cast_errors() {
                 return uint8(state.foo);
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -127,7 +136,13 @@ fn test_cast_errors() {
 
 #[test]
 fn incorrect_fields() {
-    let ns = parse_and_resolve("enum state { }", Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        "enum state { }",
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "enum ‘state’ has no fields");
 
@@ -161,7 +176,10 @@ fn incorrect_fields() {
         foo243, foo244, foo245, foo246, foo247, foo248, foo249, foo250, foo251,
         foo252, foo253, foo254, foo255, foo256
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 108 - 27
tests/substrate_tests/events.rs

@@ -11,7 +11,10 @@ fn event_decl() {
         contract c {
             event foo ();
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -20,7 +23,10 @@ fn event_decl() {
         r#"
         enum e { a1 }
         event e();"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -34,7 +40,10 @@ fn event_decl() {
         contract c {
             event e();
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -48,7 +57,10 @@ fn event_decl() {
             enum e { a1 }
             event e();
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -61,7 +73,10 @@ fn event_decl() {
         contract c {
             event foo (mapping (bool => uint) x);
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -78,7 +93,10 @@ fn event_decl() {
         contract c {
             event foo (s x);
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -91,7 +109,10 @@ fn event_decl() {
         contract c {
             event foo (bool x, uint32 y, address x);
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -104,7 +125,10 @@ fn event_decl() {
         contract c {
             event foo (bool indexed f1, bool indexed f2, bool indexed f3, bool indexed f4);
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -117,7 +141,10 @@ fn event_decl() {
         contract c {
             event foo (bool indexed f1, bool indexed f2, bool indexed f3);
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -127,7 +154,10 @@ fn event_decl() {
         contract c {
             event foo (bool indexed f1, bool indexed f2, bool indexed f3, bool indexed f4, bool indexed f5) anonymous;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -140,7 +170,10 @@ fn event_decl() {
         contract c {
             event foo (bool indexed f1, bool indexed f2, bool indexed f3, bool indexed f4) anonymous;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -155,7 +188,10 @@ fn emit() {
                 emit 1 ();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -171,7 +207,10 @@ fn emit() {
                 emit foo {};
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -187,7 +226,10 @@ fn emit() {
                 emit foo (true);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -203,7 +245,10 @@ fn emit() {
                 emit foo (true, "ab");
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -219,7 +264,10 @@ fn emit() {
                 emit foo ({a:true, a:"ab"});
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -235,7 +283,10 @@ fn emit() {
                 emit foo ({a:true, b:"ab"});
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -251,7 +302,10 @@ fn emit() {
                 emit foo (true, 102);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -342,7 +396,10 @@ fn event_imported() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -376,7 +433,10 @@ fn event_imported() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -410,7 +470,10 @@ fn event_imported() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -442,7 +505,10 @@ fn event_imported() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -461,7 +527,10 @@ fn inherited() {
                 emit foo(true, 1);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -482,7 +551,10 @@ fn signatures() {
                 emit foo(true, 1);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -499,7 +571,10 @@ fn signatures() {
                 emit foo(true, 1);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -516,7 +591,10 @@ fn signatures() {
                 emit foo(true, 1);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -532,7 +610,10 @@ fn signatures() {
                 emit foo(true, 1);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);

+ 48 - 12
tests/substrate_tests/expressions.rs

@@ -251,7 +251,10 @@ fn test_cast_errors() {
                 bool is_nonzero = bar;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -265,7 +268,10 @@ fn test_cast_errors() {
                 return (foo < bar);
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -280,7 +286,10 @@ fn test_cast_errors() {
                 return false;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -293,7 +302,10 @@ fn test_cast_errors() {
                 return false;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -330,7 +342,10 @@ fn test_cast_errors() {
                 set_x(uint32(b));
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -968,7 +983,10 @@ fn power() {
                 return base ** exp;
             }
        }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -982,7 +1000,10 @@ fn power() {
                 return base ** exp;
             }
        }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -996,7 +1017,10 @@ fn power() {
                 return base ** exp;
             }
        }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1381,7 +1405,10 @@ fn destructure() {
                 (a, b) = (1, 2, 3);
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1398,7 +1425,10 @@ fn destructure() {
                 (c, b) = (1, 2);
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "`c\' is not found");
@@ -1412,7 +1442,10 @@ fn destructure() {
                 (a memory, b) = (1, 2);
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1429,7 +1462,10 @@ fn destructure() {
                 (a , b) = (1, );
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "stray comma");

+ 7 - 1
tests/substrate_tests/first.rs

@@ -7,7 +7,13 @@ use solang::Target;
 #[test]
 fn simple_solidiy_compile_and_run() {
     // try empty file
-    let ns = parse_and_resolve("", Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        "",
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     no_errors(ns.diagnostics);
 

+ 36 - 9
tests/substrate_tests/format.rs

@@ -13,7 +13,10 @@ fn parse() {
                 s.format();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -28,7 +31,10 @@ fn parse() {
                 string s = "foo{".format();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "missing closing ‘}’");
@@ -40,7 +46,10 @@ fn parse() {
                 string s = "foo{d".format();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "unexpected format char ‘d’");
@@ -52,7 +61,10 @@ fn parse() {
                 string s = "foo{:".format();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "missing format specifier");
@@ -64,7 +76,10 @@ fn parse() {
                 string s = "foo{:}s".format();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "missing argument to format");
@@ -76,7 +91,10 @@ fn parse() {
                 string s = "f{{oo}s".format();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "unmatched ‘}’");
@@ -88,7 +106,10 @@ fn parse() {
                 string s = "f{{oo}}s".format(true);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -103,7 +124,10 @@ fn parse() {
                 string s = "{}" "{:x}s".format(1, true);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -118,7 +142,10 @@ fn parse() {
                 string s = "{}" "{:x}s".format(1, 0xcafe);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);

+ 72 - 18
tests/substrate_tests/function_types.rs

@@ -11,7 +11,10 @@ fn decls() {
                 function() public a;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -25,7 +28,10 @@ fn decls() {
                 function() private a;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -39,7 +45,10 @@ fn decls() {
                 function() returns (bool) internal a;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -53,7 +62,10 @@ fn decls() {
                 function() returns (bool) pure a;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -67,7 +79,10 @@ fn decls() {
                 function() returns (bool x) a;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -81,7 +96,10 @@ fn decls() {
                 function(address tre) returns (bool) a;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -95,7 +113,10 @@ fn decls() {
             function foo(function(address) pure internal returns (bool) a) public {
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -108,7 +129,10 @@ fn decls() {
             function foo() public returns (function(address) pure internal returns (bool) a) {
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -120,7 +144,10 @@ fn decls() {
         "contract test {
             function(address) pure internal returns (bool) public a;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -139,7 +166,10 @@ fn assign() {
                 function(int32) pure a = x;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -155,7 +185,10 @@ fn assign() {
                 function(int32) view a = x;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -171,7 +204,10 @@ fn assign() {
                 function(int32) a = x;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -189,7 +225,10 @@ fn assign() {
                 function(int32) a = x;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -207,7 +246,10 @@ fn assign() {
                 function(int32) returns (bool) a = x;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -425,7 +467,10 @@ fn ext() {
                 return false;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -444,7 +489,10 @@ fn ext() {
                 return false;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -467,7 +515,10 @@ fn ext() {
                 return false;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -625,7 +676,10 @@ fn variable_or_func_type() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);

+ 266 - 50
tests/substrate_tests/functions.rs

@@ -13,7 +13,10 @@ fn constructors() {
         contract test {
             constructor() internal {}
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -26,7 +29,10 @@ fn constructors() {
         contract test {
             constructor() virtual {}
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -128,7 +134,10 @@ fn fallback() {
                 result = 356;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -250,7 +259,10 @@ fn mutability() {
                 return foo;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -264,7 +276,10 @@ fn mutability() {
                 return 102;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -278,7 +293,10 @@ fn mutability() {
                 return foo[0];
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -294,7 +312,10 @@ fn mutability() {
                 foo = 102;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -308,7 +329,10 @@ fn mutability() {
                 foo[0] = 102;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -322,7 +346,10 @@ fn mutability() {
                 (bool f, bytes memory res) = a.call(hex"0102");
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -336,7 +363,10 @@ fn mutability() {
                 (f, res) = a.call(hex"0102");
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(ns.diagnostics.len(), 1);
@@ -348,7 +378,10 @@ fn mutability() {
                 return true;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_warnings(&ns.diagnostics);
@@ -361,7 +394,10 @@ fn mutability() {
                 return foo;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_warnings_errors(ns.diagnostics);
@@ -372,7 +408,10 @@ fn mutability() {
                 return 102;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_warnings_errors(ns.diagnostics);
@@ -383,7 +422,10 @@ fn mutability() {
                 return 102;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -395,7 +437,10 @@ fn mutability() {
         "contract test {
             int64 constant public foo = 1844674;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_warnings_errors(ns.diagnostics);
@@ -423,7 +468,13 @@ fn shadowing() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_warning(ns.diagnostics),
@@ -463,7 +514,13 @@ fn scopes() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "`a\' is not found");
 
@@ -477,7 +534,13 @@ fn scopes() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "`i\' is not found");
 }
@@ -494,7 +557,13 @@ fn for_forever() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "unreachable statement");
 }
@@ -620,7 +689,13 @@ fn args_and_returns() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "arg1 is already declared");
 
@@ -630,7 +705,13 @@ fn args_and_returns() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "arg2 is already declared");
 
@@ -640,7 +721,13 @@ fn args_and_returns() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "missing return statement");
 
@@ -663,7 +750,13 @@ fn args_and_returns() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "missing return statement");
 
@@ -702,7 +795,13 @@ fn named_argument_call() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -719,7 +818,13 @@ fn named_argument_call() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "unexpected array type");
 
@@ -733,7 +838,13 @@ fn named_argument_call() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -750,7 +861,13 @@ fn named_argument_call() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -767,7 +884,13 @@ fn named_argument_call() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -811,7 +934,13 @@ fn positional_argument_call() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -828,7 +957,13 @@ fn positional_argument_call() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(first_error(ns.diagnostics), "expression is not an array");
 
@@ -842,7 +977,13 @@ fn positional_argument_call() {
         }
     }";
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -958,7 +1099,13 @@ fn payable() {
             }
         }"##;
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -976,7 +1123,13 @@ fn payable() {
             }
         }"##;
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -994,7 +1147,13 @@ fn payable() {
             }
         }"##;
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -1012,7 +1171,13 @@ fn payable() {
             }
         }"##;
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -1027,7 +1192,13 @@ fn payable() {
             }
         }"##;
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -1042,7 +1213,13 @@ fn payable() {
             }
         }"##;
 
-    let ns = parse_and_resolve(src, Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        src,
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -1056,7 +1233,10 @@ fn global_functions() {
         r##"
         function() {}
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "missing function name");
@@ -1065,7 +1245,10 @@ fn global_functions() {
         r##"
         function x();
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "missing function body");
@@ -1074,7 +1257,10 @@ fn global_functions() {
         r##"
         function x() virtual {}
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1086,7 +1272,10 @@ fn global_functions() {
         r##"
         function x() override {}
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1098,7 +1287,10 @@ fn global_functions() {
         r##"
         function x() feyla {}
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1110,7 +1302,10 @@ fn global_functions() {
         r##"
         function x() feyla {}
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1124,7 +1319,10 @@ fn global_functions() {
 
         function x() pure { emit foo(true); }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1136,7 +1334,10 @@ fn global_functions() {
         r##"
         function x(int[] storage x) pure returns (int) { return x[1]; }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1153,7 +1354,10 @@ fn global_functions() {
 
         function x(S storage x) view { x.f1 = 102; }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1167,7 +1371,10 @@ fn global_functions() {
         function x(int128) pure { return 102; }
         function x(int128) pure { return 132; }
         "##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1245,7 +1452,10 @@ fn return_not_returns() {
                 return 1;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1258,14 +1468,20 @@ fn return_not_returns() {
 fn stray_semicolon() {
     let ns = parse_and_resolve(
         "struct a { uint32 f1; };",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "stray semicolon");
 
     let ns = parse_and_resolve(
         "contract x { struct a { uint32 f1; }; }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "stray semicolon");

+ 80 - 20
tests/substrate_tests/imports.rs

@@ -29,7 +29,10 @@ fn enum_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -59,7 +62,10 @@ fn enum_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -89,7 +95,10 @@ fn enum_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -115,7 +124,10 @@ fn enum_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -137,7 +149,10 @@ fn enum_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -158,7 +173,10 @@ fn enum_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -194,7 +212,10 @@ fn struct_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -224,7 +245,10 @@ fn struct_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "type ‘struct_a’ not found");
@@ -265,7 +289,10 @@ fn contract_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -312,7 +339,10 @@ fn contract_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -359,7 +389,10 @@ fn contract_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -386,7 +419,10 @@ fn circular_import() {
     let ns = solang::parse_and_resolve(
         "self.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -431,7 +467,10 @@ fn circular_import() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -469,7 +508,10 @@ fn import_symbol() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -508,7 +550,10 @@ fn import_symbol() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -547,7 +592,10 @@ fn import_symbol() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -596,7 +644,10 @@ fn import_symbol() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -650,7 +701,10 @@ fn enum_import_chain() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -701,7 +755,10 @@ fn enum_import_chain() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -754,7 +811,10 @@ fn import_base_dir() {
     let ns = solang::parse_and_resolve(
         "a.sol",
         &mut cache,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);

+ 304 - 76
tests/substrate_tests/inheritance.rs

@@ -11,7 +11,10 @@ fn test_virtual() {
         contract c {
             function test() public;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -24,7 +27,10 @@ fn test_virtual() {
         contract c {
             function test() virtual public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -35,7 +41,10 @@ fn test_virtual() {
             function test() virtual public;
             function test2() virtual public;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -62,7 +71,10 @@ fn test_abstract() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -86,7 +98,10 @@ fn test_abstract() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -120,7 +135,10 @@ fn test_abstract() {
         "a.sol",
         &mut cache,
         inkwell::OptimizationLevel::Default,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
         false,
     );
 
@@ -158,7 +176,10 @@ fn test_abstract() {
         "a.sol",
         &mut cache,
         inkwell::OptimizationLevel::Default,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
         false,
     );
 
@@ -176,7 +197,10 @@ fn test_interface() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -190,7 +214,10 @@ fn test_interface() {
             function bar() external {}
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -204,7 +231,10 @@ fn test_interface() {
             function bar() private;
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -218,7 +248,10 @@ fn test_interface() {
             function bar() internal;
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -236,7 +269,10 @@ fn test_interface() {
             function f() internal {}
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -254,7 +290,10 @@ fn test_interface() {
             function f() internal {}
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -268,7 +307,10 @@ fn test_interface() {
             function foo() virtual external;
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -282,7 +324,10 @@ fn test_interface() {
             int x;
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -296,7 +341,10 @@ fn test_interface() {
             int constant x = 1;
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -325,7 +373,10 @@ fn test_interface() {
             function f2(address a) public {}
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -340,7 +391,10 @@ fn inherit() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -355,7 +409,10 @@ fn inherit() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "contract ‘foo’ not found");
@@ -372,7 +429,10 @@ fn inherit() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -392,7 +452,10 @@ fn inherit() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -417,7 +480,10 @@ fn inherit() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -447,7 +513,10 @@ fn inherit() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -470,7 +539,10 @@ fn inherit_types() {
             enum enum_x { x1, x2 }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -495,7 +567,10 @@ fn inherit_types() {
             enum enum_x { x1, x2 }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -520,7 +595,10 @@ fn inherit_types() {
             enum enum_x { x1, x2 }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -537,7 +615,10 @@ fn inherit_types() {
             enum enum_x { x1, x2 }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "type ‘enum_x’ not found");
@@ -555,7 +636,10 @@ fn inherit_types() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -578,7 +662,10 @@ fn inherit_types() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "already defined ‘foo’");
@@ -598,7 +685,10 @@ fn inherit_variables() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -615,7 +705,10 @@ fn inherit_variables() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "`foo\' is not found");
@@ -636,7 +729,10 @@ fn inherit_variables() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -657,7 +753,10 @@ fn inherit_variables() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -674,7 +773,10 @@ fn inherit_variables() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -779,7 +881,10 @@ fn call_inherited_function() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "cannot call private function");
@@ -798,7 +903,10 @@ fn call_inherited_function() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "cannot call private function");
@@ -821,7 +929,10 @@ fn call_inherited_function() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -927,7 +1038,10 @@ fn test_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -943,7 +1057,10 @@ fn test_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -963,7 +1080,10 @@ fn test_override() {
             function f() private {}
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -979,7 +1099,10 @@ fn test_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1001,7 +1124,10 @@ fn test_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1027,7 +1153,10 @@ fn test_override() {
             uint64 public x;
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1047,7 +1176,10 @@ fn test_override() {
                 x = 2;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1075,7 +1207,10 @@ fn test_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -1163,7 +1298,10 @@ fn test_override() {
                 function bar(int x) public { print ("foo"); }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1181,7 +1319,10 @@ fn test_override() {
                 function bar(int64 x) public override;
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1212,7 +1353,10 @@ fn multiple_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1240,7 +1384,10 @@ fn multiple_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1274,7 +1421,10 @@ fn multiple_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1302,7 +1452,10 @@ fn multiple_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1330,7 +1483,10 @@ fn multiple_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1362,7 +1518,10 @@ fn multiple_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1394,7 +1553,10 @@ fn multiple_override() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1420,7 +1582,10 @@ fn base_contract() {
                 return a + 102;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1439,7 +1604,10 @@ fn base_contract() {
                 return a + 102;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1493,7 +1661,10 @@ fn base_contract_on_constructor() {
 
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1516,7 +1687,10 @@ fn base_contract_on_constructor() {
 
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1531,7 +1705,10 @@ fn base_contract_on_constructor() {
 
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1546,7 +1723,10 @@ fn base_contract_on_constructor() {
 
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1563,7 +1743,10 @@ fn base_contract_on_constructor() {
         contract apex is base {
                 function foo() pure public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1581,7 +1764,10 @@ fn base_contract_on_constructor() {
             constructor() base(true) base(false) {}
             function foo() pure public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1707,7 +1893,10 @@ fn base_contract_on_constructor() {
             function get_foo() public returns (int64) { return foo; }
             constructor(int64 z) { foo = z; }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1730,7 +1919,10 @@ fn base_contract_on_constructor() {
             function get_foo() public returns (int64) { return foo; }
             constructor(int64 z) { foo = z; }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "duplicate base contract ‘b’");
@@ -1750,7 +1942,10 @@ fn base_contract_on_constructor() {
             function get_foo() public returns (int64) { return foo; }
             constructor(int64 z) { foo = z; }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1835,7 +2030,10 @@ fn simple_interface() {
                 return a * 2;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -1903,7 +2101,10 @@ fn cast_contract() {
                 return a / b;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -1919,7 +2120,10 @@ fn cast_contract() {
                 foo y = x;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1932,7 +2136,10 @@ fn cast_contract() {
 fn test_super() {
     let ns = parse_and_resolve(
         r#"contract super {}"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1944,7 +2151,10 @@ fn test_super() {
         r#"
         function f1() { super.a(); }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -1963,7 +2173,10 @@ fn test_super() {
                 super.f2();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "unknown function or type ‘f2’");
@@ -2071,7 +2284,10 @@ fn mutability() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -2091,7 +2307,10 @@ fn mutability() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -2116,7 +2335,10 @@ fn visibility() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -2133,7 +2355,10 @@ fn visibility() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -2153,7 +2378,10 @@ fn visibility() {
             }
         }
         "#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 64 - 16
tests/substrate_tests/libraries.rs

@@ -10,7 +10,10 @@ fn restrictions() {
         library c {
             constructor() {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -23,7 +26,10 @@ fn restrictions() {
         library c {
             receive() internal {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -36,7 +42,10 @@ fn restrictions() {
         library c {
             fallback() internal {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -49,7 +58,10 @@ fn restrictions() {
         library c {
             function f() public payable {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -62,7 +74,10 @@ fn restrictions() {
         library c {
             function foo() virtual public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -75,7 +90,10 @@ fn restrictions() {
         library c {
             function foo() override public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -88,7 +106,10 @@ fn restrictions() {
         library c is x {
             fallback() internal {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -105,7 +126,10 @@ fn restrictions() {
         contract a is c {
             function bar() public { }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -118,7 +142,10 @@ fn restrictions() {
         library c {
             int x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -174,7 +201,10 @@ fn using() {
         contract c {
             using x for x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "library ‘x’ not found");
@@ -188,7 +218,10 @@ fn using() {
         contract c {
             using x for x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -207,7 +240,10 @@ fn using() {
         contract c {
             using x for asdf;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "type ‘asdf’ not found");
@@ -223,7 +259,10 @@ fn using() {
         contract c {
             using x for x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -320,7 +359,10 @@ fn using() {
                 return a > b ? a : b;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "method ‘max’ does not exist");
@@ -340,7 +382,10 @@ fn using() {
                 return a > b ? a : b;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -368,7 +413,10 @@ fn using() {
                 return a;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 4 - 1
tests/substrate_tests/loops.rs

@@ -15,7 +15,10 @@ fn test_infinite_loop() {
                 return 0;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "unreachable statement");

+ 40 - 10
tests/substrate_tests/mappings.rs

@@ -22,7 +22,10 @@ fn bad_mapping_declares() {
                 x.data[1] = address(1);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -35,7 +38,10 @@ fn bad_mapping_declares() {
         contract c {
             mapping(uint[] => address) data;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -51,7 +57,10 @@ fn bad_mapping_declares() {
             }
             mapping(foo => address) data;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -65,7 +74,10 @@ fn bad_mapping_declares() {
             mapping(int => address) data;
             mapping(data => address) data2;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "‘data’ is a contract variable");
@@ -77,7 +89,10 @@ fn bad_mapping_declares() {
                 //
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -92,7 +107,10 @@ fn bad_mapping_declares() {
                 //
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -107,7 +125,10 @@ fn bad_mapping_declares() {
                 //
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -122,7 +143,10 @@ fn bad_mapping_declares() {
                 //
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -138,7 +162,10 @@ fn bad_mapping_declares() {
                 //
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -154,7 +181,10 @@ fn bad_mapping_declares() {
                 delete data;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 60 - 15
tests/substrate_tests/modifier.rs

@@ -10,7 +10,10 @@ fn declare() {
         contract c {
             modifier foo() public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -23,7 +26,10 @@ fn declare() {
         contract c {
             modifier foo() internal {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -36,7 +42,10 @@ fn declare() {
         contract c {
             modifier foo() payable {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -49,7 +58,10 @@ fn declare() {
         contract c {
             modifier foo() pure {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -62,7 +74,10 @@ fn declare() {
         contract c {
             modifier foo bar {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -75,7 +90,10 @@ fn declare() {
         contract c {
             modifier foo() {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "missing ‘_’ in modifier");
@@ -91,7 +109,10 @@ fn declare() {
                 }
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -107,7 +128,10 @@ fn declare() {
                 foo();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -122,7 +146,10 @@ fn declare() {
                 _;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -140,7 +167,10 @@ fn function_modifier() {
 
             function bar() foo2 public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "unknown modifier ‘foo2’");
@@ -152,7 +182,10 @@ fn function_modifier() {
 
             function bar() foo(1) public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -167,7 +200,10 @@ fn function_modifier() {
 
             function bar(bool x) foo(x) public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -508,7 +544,10 @@ fn mutability() {
 
             function bar() foo(var) public pure {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -524,7 +563,10 @@ fn mutability() {
 
             function bar() foo() public pure {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -543,7 +585,10 @@ fn mutability() {
         contract apex is base {
             function foo() public override {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 127 - 34
tests/substrate_tests/primitives.rs

@@ -91,7 +91,10 @@ fn test_literal_overflow() {
         "contract test {
             uint8 foo = 300;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -103,7 +106,10 @@ fn test_literal_overflow() {
         "contract test {
             uint16 foo = 0x10000;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -115,7 +121,10 @@ fn test_literal_overflow() {
         "contract test {
             int8 foo = 0x8_0;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -127,7 +136,10 @@ fn test_literal_overflow() {
         "contract test {
             int8 foo = -129;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -139,7 +151,10 @@ fn test_literal_overflow() {
         "contract test {
             int8 foo = 127;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -148,7 +163,10 @@ fn test_literal_overflow() {
         "contract test {
             int8 foo = -128;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -157,7 +175,10 @@ fn test_literal_overflow() {
         "contract test {
             uint8 foo = 255;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -166,7 +187,10 @@ fn test_literal_overflow() {
         "contract test {
             uint8 foo = -1_30;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -178,7 +202,10 @@ fn test_literal_overflow() {
         "contract test {
             int64 foo = 1844674_4073709551616;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -190,7 +217,10 @@ fn test_literal_overflow() {
         "contract test {
             bytes4 foo = 0xf12233;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -202,7 +232,10 @@ fn test_literal_overflow() {
         "contract test {
             bytes4 foo = 0x0122334455;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -214,7 +247,10 @@ fn test_literal_overflow() {
         "contract test {
             bytes4 foo = 0x00223344;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -311,7 +347,10 @@ fn address() {
         "contract test {
             address  foo = 0x1844674_4073709551616;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -323,7 +362,10 @@ fn address() {
         "contract test {
             address foo = 0xa368df6dfcd5ba7b0bc108af09e98e4655e35a2c3b2e2d5e3eae6c6f7cd8d2d4;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -335,7 +377,10 @@ fn address() {
         r#"contract test {
             address foo = address"5GBWmgdFAMqm8ZgAHGobqDqX6tjLxJhv53ygjNtaaAn3sje";
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -347,7 +392,10 @@ fn address() {
         r#"contract test {
             address foo = address"5GBWmgdFAMqm8ZgAHGobqDqX6tjLxJhv53ygjNtaaAn3sj%Z";
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -359,7 +407,10 @@ fn address() {
         r#"contract test {
             address foo = address"5GBWmgdFAMqm8ZgAHGobqDqX6tjLxJhv53ygjNtaaAn3sjZZ";
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -371,7 +422,10 @@ fn address() {
         r#"contract test {
             address foo = address"5GBWmgdFAMqm8ZgAHGobqDqX6tjLxJhv53ygjNtaaAn3sjeZ";
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -384,7 +438,7 @@ fn address() {
                 return foo > address(0);
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate { address_length: 32, value_length:  16 },
     );
 
     no_errors(ns.diagnostics);
@@ -397,7 +451,7 @@ fn address() {
                 return foo + address(1);
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate { address_length: 32, value_length:  16 },
     );
 
     assert_eq!(
@@ -413,7 +467,7 @@ fn address() {
                 return foo | address(1);
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate { address_length: 32, value_length:  16 },
     );
 
     assert_eq!(
@@ -425,7 +479,10 @@ fn address() {
         "contract test {
             address foo = 0x5b0Ddf2835f0A76c96D6113D47F6482e51a55487;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -482,7 +539,10 @@ fn address_payable_type() {
                 address b = a;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -499,7 +559,10 @@ fn address_payable_type() {
                 return b == a;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -516,7 +579,10 @@ fn address_payable_type() {
             function test() public {
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -536,7 +602,10 @@ fn address_payable_type() {
             function test() public {
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -556,7 +625,10 @@ fn address_payable_type() {
             function test() public {
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -568,7 +640,10 @@ fn address_payable_type() {
                 address b = address(a);
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -580,7 +655,10 @@ fn address_payable_type() {
                 address b = a;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -596,7 +674,10 @@ fn address_payable_type() {
                 address payable b = address payable(a);
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -665,7 +746,10 @@ fn type_name() {
                 int32 x = type(bool).max;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -714,7 +798,10 @@ fn units() {
                 int32 x = 1 ether;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -729,7 +816,10 @@ fn units() {
                 int32 x = 0xa days;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -744,7 +834,10 @@ fn units() {
                 int32 x = (1 + 2) days;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 44 - 11
tests/substrate_tests/strings.rs

@@ -16,7 +16,10 @@ fn basic_tests() {
                     f[0] = 102;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -31,7 +34,10 @@ fn basic_tests() {
                     bytes f = new string(2);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -46,7 +52,10 @@ fn basic_tests() {
                     string f = new bytes(2);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -61,7 +70,10 @@ fn basic_tests() {
                     string f = string(new bytes(2));
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -73,7 +85,10 @@ fn basic_tests() {
                     bytes f = bytes(new string(2));
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -678,7 +693,10 @@ fn string_escape() {
                     string f = "\x";
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -693,7 +711,10 @@ fn string_escape() {
                     string f = "\x9k";
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -708,7 +729,10 @@ fn string_escape() {
                     string f = "\xたこ";
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -723,7 +747,10 @@ fn string_escape() {
                     string f = "\u";
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -738,7 +765,10 @@ fn string_escape() {
                     string f = "\uたこ焼き";
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -753,7 +783,10 @@ fn string_escape() {
                     string f = "\u9kff";
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 52 - 13
tests/substrate_tests/structs.rs

@@ -21,7 +21,10 @@ fn parse_structs() {
                 uint a;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -37,7 +40,10 @@ fn parse_structs() {
                 uint storage b;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -53,7 +59,10 @@ fn parse_structs() {
                 uint calldata b;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -69,7 +78,10 @@ fn parse_structs() {
                 uint calldata b;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -83,7 +95,10 @@ fn parse_structs() {
             struct Foo {
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -98,7 +113,10 @@ fn parse_structs() {
                 boolean x;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "type ‘boolean’ not found");
@@ -112,7 +130,10 @@ fn parse_structs() {
                 Foo y;
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -137,7 +158,10 @@ fn parse_structs() {
             bytes4 selector;
             s foo;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "struct ‘s2’ has infinite size");
@@ -155,7 +179,10 @@ fn parse_structs() {
                 Foo a = Foo();
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -176,7 +203,10 @@ fn parse_structs() {
                 Foo a = Foo(true, true, true);
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -197,7 +227,10 @@ fn parse_structs() {
                 Foo a = Foo({ });
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -218,7 +251,10 @@ fn parse_structs() {
                 Foo a = Foo({ x: true, y: 1, z: 2 });
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -239,7 +275,10 @@ fn parse_structs() {
                 Foo a = Foo({ x: true, z: 1 });
             }
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "struct ‘Foo’ has no field ‘z’");

+ 111 - 27
tests/substrate_tests/tags.rs

@@ -7,7 +7,10 @@ fn contract() {
         r#"
         /// @barf
         contract test {}"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -25,7 +28,10 @@ fn contract() {
         /// @dev this is
         ///  a contract
         contract test {}"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(ns.contracts[0].tags[0].tag, "notice");
@@ -51,7 +57,10 @@ fn contract() {
          * a contract
          */
         contract test {}"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(ns.contracts[0].tags[0].tag, "notice");
@@ -66,7 +75,13 @@ fn contract() {
     assert_eq!(ns.contracts[0].tags[3].tag, "dev");
     assert_eq!(ns.contracts[0].tags[3].value, "this is a contract");
 
-    let ns = parse_and_resolve("/**\n", Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        "/**\n",
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(ns.diagnostics[0].pos, Some(Loc(0, 0, 4)));
     assert_eq!(ns.diagnostics[0].message, "end of file found in comment");
@@ -80,7 +95,10 @@ fn struct_tag() {
         struct x {
             uint32 f;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -94,7 +112,10 @@ fn struct_tag() {
         struct x {
             uint32 f;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "tag ‘@param’ no field ‘g’");
@@ -106,7 +127,10 @@ fn struct_tag() {
         struct x {
             uint32 f;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -122,7 +146,10 @@ fn struct_tag() {
             uint32 f1;
             uint32 f2;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(ns.diagnostics.len(), 0);
@@ -144,7 +171,10 @@ fn event_tag() {
         event x (
             uint32 f
         );"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -158,7 +188,10 @@ fn event_tag() {
         event x (
             uint32 f
         );"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "tag ‘@param’ no field ‘g’");
@@ -170,7 +203,10 @@ fn event_tag() {
         event x (
             uint32 f
         );"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -186,7 +222,10 @@ fn event_tag() {
             uint32 f1,
             uint32 f2
         );"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     //Event never emitted generates a warning
@@ -211,7 +250,10 @@ fn event_tag() {
                 uint32 f2
             );
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     //Event never emitted generates a warning
@@ -238,7 +280,10 @@ fn enum_tag() {
         enum x {
             foo1
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -252,7 +297,10 @@ fn enum_tag() {
          *  @dev bla bla bla
          * @author f2 bar */
         enum x { x1 }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(ns.diagnostics.len(), 0);
@@ -274,7 +322,10 @@ fn functions() {
             /// @param
             function foo() public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -289,7 +340,10 @@ fn functions() {
             /// @param g
             function foo(int f) public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "tag ‘@param’ no field ‘g’");
@@ -303,7 +357,10 @@ fn functions() {
              */
             function foo(int f) public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -317,7 +374,10 @@ fn functions() {
             /// @return so here we are
             function foo() public {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -331,7 +391,10 @@ fn functions() {
             /// @return so here we are
             function foo() public returns (int a, bool) {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "tag ‘@return’ no field ‘so’");
@@ -342,7 +405,10 @@ fn functions() {
             /// @return
             function foo() public returns (int a, bool b) {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -357,7 +423,10 @@ fn functions() {
             /// @return a barf
             function foo() public returns (int a, bool b) {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -371,7 +440,10 @@ fn functions() {
             /// @inheritdoc
             function foo() public returns (int a, bool b) {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -385,7 +457,10 @@ fn functions() {
             /// @inheritdoc b
             function foo() public returns (int a, bool b) {}
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -403,7 +478,10 @@ fn functions() {
         }
 
         contract b {}"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(ns.diagnostics.len(), 5);
@@ -427,7 +505,10 @@ fn variables() {
             /// @param
             int x;
         }"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -445,7 +526,10 @@ fn variables() {
         }
 
         contract b {}"#,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     //Variable 'y' has never been used (one item error in diagnostic)

+ 80 - 20
tests/substrate_tests/value.rs

@@ -21,7 +21,10 @@ fn external_call_value() {
                 a f = new a();
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -44,7 +47,10 @@ fn external_call_value() {
                 a f = new a();
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -67,7 +73,10 @@ fn external_call_value() {
                 a f = new a();
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -90,7 +99,10 @@ fn external_call_value() {
                 a f = new a();
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -113,7 +125,10 @@ fn external_call_value() {
                 a f = new a();
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -136,7 +151,10 @@ fn external_call_value() {
                 a f = new a();
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -159,7 +177,10 @@ fn external_call_value() {
                 a f = new a();
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "missing call arguments");
@@ -179,7 +200,10 @@ fn external_call_value() {
                 f.test{value: 1023}(501);
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -202,7 +226,10 @@ fn external_call_value() {
                 f.test{value: 1023}({l: 501});
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -226,7 +253,10 @@ fn external_call_value() {
                 f.test{value: x}({l: 501});
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -249,7 +279,10 @@ fn external_call_value() {
                 f.test{value: 2-2}({l: 501});
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -269,7 +302,10 @@ fn external_call_value() {
                 f.test{value: 0*10}(501);
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -549,7 +585,10 @@ fn this_address() {
                 return payable(this);
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -561,7 +600,10 @@ fn this_address() {
                 return this;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -576,7 +618,10 @@ fn this_address() {
                 this = other;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "expression is not assignable");
@@ -665,7 +710,10 @@ fn this_address() {
                 s = n;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -687,7 +735,10 @@ fn this_address() {
                 s = n;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -705,7 +756,10 @@ fn balance() {
                 return j.balance;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -720,7 +774,10 @@ fn balance() {
                 return j.balance;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -735,7 +792,10 @@ fn balance() {
                 return j.balance;
             }
         }"##,
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(

+ 110 - 26
tests/substrate_tests/variables.rs

@@ -8,7 +8,10 @@ fn variable_size() {
             function foo(int[12131231313213] memory y) public {}
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -21,7 +24,10 @@ fn variable_size() {
             function foo() public returns (int[12131231313213] memory y) {}
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -36,7 +42,10 @@ fn variable_size() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -56,7 +65,10 @@ fn immutable() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -73,7 +85,10 @@ fn immutable() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -90,7 +105,10 @@ fn immutable() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -107,7 +125,10 @@ fn immutable() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -126,7 +147,10 @@ fn immutable() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -139,7 +163,10 @@ fn immutable() {
             int immutable public immutable y = 1;
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -155,7 +182,10 @@ fn override_attribute() {
             int override y = 1;
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -168,7 +198,10 @@ fn override_attribute() {
             int override internal y = 1;
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -181,7 +214,10 @@ fn override_attribute() {
             int override private y = 1;
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -194,7 +230,10 @@ fn override_attribute() {
             int override override y = 1;
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -213,7 +252,10 @@ fn override_attribute() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -232,7 +274,10 @@ fn override_attribute() {
             }
         }
         ",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     no_errors(ns.diagnostics);
@@ -250,7 +295,10 @@ fn test_variable_errors() {
                 return a * b;
             }
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "`b' is not found");
@@ -264,7 +312,10 @@ fn test_variable_initializer_errors() {
             uint x = 102;
             uint constant y = x + 5;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -280,7 +331,10 @@ fn test_variable_initializer_errors() {
             }
             uint constant y = foo() + 5;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -294,7 +348,10 @@ fn test_variable_initializer_errors() {
             uint x = y + 102;
             uint y = 102;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "`y' is not found");
@@ -305,7 +362,10 @@ fn test_variable_initializer_errors() {
             uint x = y + 102;
             uint constant y = 102;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "`y' is not found");
@@ -315,7 +375,10 @@ fn test_variable_initializer_errors() {
         "contract test {
             uint x = x + 102;
         }",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(first_error(ns.diagnostics), "`x' is not found");
@@ -323,7 +386,13 @@ fn test_variable_initializer_errors() {
 
 #[test]
 fn global_constants() {
-    let ns = parse_and_resolve("uint x = 102;", Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        "uint x = 102;",
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -332,7 +401,10 @@ fn global_constants() {
 
     let ns = parse_and_resolve(
         "uint constant public x = 102;",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -342,7 +414,10 @@ fn global_constants() {
 
     let ns = parse_and_resolve(
         "uint constant external x = 102;",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(
@@ -350,7 +425,13 @@ fn global_constants() {
         "‘external’: global variable cannot have visibility specifier"
     );
 
-    let ns = parse_and_resolve("uint constant x;", Target::Substrate { address_length: 32 });
+    let ns = parse_and_resolve(
+        "uint constant x;",
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
+    );
 
     assert_eq!(
         first_error(ns.diagnostics),
@@ -359,7 +440,10 @@ fn global_constants() {
 
     let ns = parse_and_resolve(
         "uint constant test = 5; contract test {}",
-        Target::Substrate { address_length: 32 },
+        Target::Substrate {
+            address_length: 32,
+            value_length: 16,
+        },
     );
 
     assert_eq!(