//! This module tests the library's analysis capabilities on the `House`
//! contract`.
#![cfg(test)]

use storage_layout_extractor::{
    tc::abi::{AbiType, StructElement},
    watchdog::LazyWatchdog,
};

mod common;

/// Tests the library on the bytecode of the House contract deployed
/// [here](https://etherscan.io/address/0x7cbb952a448672eb6ea3cc869cdcec6cf6163e29#code).
#[test]
fn correctly_generates_a_layout() -> anyhow::Result<()> {
    // Create the extractor
    let bytecode = "0x60806040526004361061023a5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c2781146102aa57806303f3ad77146102f05780630960c477146103b857806309c95e10146103f45780630afb1b9d1461043b5780630f768131146104f55780631604a1271461050a5780631a3ac4811461054257806322af00fa1461056c57806326266dd1146106415780632e1a7d4d146106fb5780632f674c9114610725578063357401f51461075e57806335bdac34146107885780633d09a0a3146107c157806346214518146107f457806349bc79851461082d578063584f9ba9146108e05780635969b178146108f557806359bdafe9146109bb57806360128749146109e55780636369313d14610a245780636413ac2314610a3957806365b1b92d14610a6c578063669be96114610a815780636df0604814610aab57806371ff091714610ae4578063781687b614610b975780637c170a1314610db65780637df2a57414610de057806389897c6514610e135780638bdc16fe14610e4c5780638c69c11214610e855780638c6aa4b514610e9a5780638cee8a1314610ed35780638da5cb5b14610f03578063a57229bd14610f18578063a74040c814610f4b578063ae11a3fc1461103c578063b0dc1a63146110f6578063befa1e2f14611120578063d1891d9414611135578063d4213c4e146111e8578063e3d670d7146113a9578063e8244d48146113dc578063f2fde38b14611406578063fcc6a19914611439575b336000908152601c6020526040902054610254903461146c565b336000818152601c6020908152604091829020939093558051348152600193810193909352805191927fe1ad1162eeaaa41101454531343fcf2c339a2e59af62648980c06bd7e3f333e2929081900390910190a2005b3480156102b657600080fd5b506102d4600480360360208110156102cd57600080fd5b5035611482565b60408051600160a060020a039092168252519081900360200190f35b3480156102fc57600080fd5b506103b66004803603608081101561031357600080fd5b8135916020810135916040820135919081019060808101606082013564010000000081111561034157600080fd5b82018360208201111561035357600080fd5b8035906020019184600183028401116401000000008311171561037557600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506114aa945050505050565b005b3480156103c457600080fd5b506103e2600480360360208110156103db57600080fd5b5035611b8d565b60408051918252519081900360200190f35b34801561040057600080fd5b506104276004803603602081101561041757600080fd5b5035600160a060020a0316611b9e565b604080519115158252519081900360200190f35b34801561044757600080fd5b506103b66004803603604081101561045e57600080fd5b8135919081019060408101602082013564010000000081111561048057600080fd5b82018360208201111561049257600080fd5b803590602001918460018302840111640100000000831117156104b457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611bba945050505050565b34801561050157600080fd5b506103e2611f2f565b34801561051657600080fd5b506103e26004803603606081101561052d57600080fd5b50803590602081013515159060400135611f35565b34801561054e57600080fd5b506104276004803603602081101561056557600080fd5b50356120d3565b34801561057857600080fd5b506105966004803603602081101561058f57600080fd5b50356120e8565b604051808f81526020018e600160a060020a0316600160a060020a031681526020018d81526020018c81526020018b81526020018a1515151581526020018981526020018881526020018715151515815260200186815260200185815260200184815260200183600160a060020a0316600160a060020a0316815260200182600281111561062057fe5b60ff1681526020019e50505050505050505050505050505060405180910390f35b34801561064d57600080fd5b506103b66004803603604081101561066457600080fd5b8135919081019060408101602082013564010000000081111561068657600080fd5b82018360208201111561069857600080fd5b803590602001918460018302840111640100000000831117156106ba57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061216d945050505050565b34801561070757600080fd5b506103b66004803603602081101561071e57600080fd5b5035612881565b34801561073157600080fd5b506103e26004803603604081101561074857600080fd5b50600160a060020a0381351690602001356129fd565b34801561076a57600080fd5b506103b66004803603602081101561078157600080fd5b5035612a1a565b34801561079457600080fd5b506103b6600480360360408110156107ab57600080fd5b50600160a060020a038135169060200135612b93565b3480156107cd57600080fd5b506103e2600480360360208110156107e457600080fd5b5035600160a060020a0316612ca8565b34801561080057600080fd5b506104276004803603604081101561081757600080fd5b50600160a060020a038135169060200135612cba565b34801561083957600080fd5b506103b66004803603602081101561085057600080fd5b81019060208101813564010000000081111561086b57600080fd5b82018360208201111561087d57600080fd5b8035906020019184600183028401116401000000008311171561089f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612cda945050505050565b3480156108ec57600080fd5b506103e2612d3d565b34801561090157600080fd5b506103b66004803603608081101561091857600080fd5b8135916020810135916040820135919081019060808101606082013564010000000081111561094657600080fd5b82018360208201111561095857600080fd5b8035906020019184600183028401116401000000008311171561097a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612d43945050505050565b3480156109c757600080fd5b506103e2600480360360208110156109de57600080fd5b5035613366565b3480156109f157600080fd5b506103e260048036036060811015610a0857600080fd5b50600160a060020a038135169060208101359060400135613378565b348015610a3057600080fd5b5061042761339b565b348015610a4557600080fd5b506103e260048036036020811015610a5c57600080fd5b5035600160a060020a03166133a1565b348015610a7857600080fd5b506103b66133b3565b348015610a8d57600080fd5b506103e260048036036020811015610aa457600080fd5b503561341e565b348015610ab757600080fd5b506103e260048036036040811015610ace57600080fd5b50600160a060020a038135169060200135613430565b348015610af057600080fd5b506103b660048036036020811015610b0757600080fd5b810190602081018135640100000000811115610b2257600080fd5b820183602082011115610b3457600080fd5b80359060200191846001830284011164010000000083111715610b5657600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061344d945050505050565b348015610ba357600080fd5b50610bac6134b6565b604051808c1515151581526020018060200180602001806020018b600160a060020a0316600160a060020a031681526020018a600160a060020a0316600160a060020a03168152602001891515151581526020018881526020018781526020018681526020018060200185810385528f818151815260200191508051906020019080838360005b83811015610c4b578181015183820152602001610c33565b50505050905090810190601f168015610c785780820380516001836020036101000a031916815260200191505b5085810384528e818151815260200191508051906020019080838360005b83811015610cae578181015183820152602001610c96565b50505050905090810190601f168015610cdb5780820380516001836020036101000a031916815260200191505b5085810383528d5181528d516020918201918f019080838360005b83811015610d0e578181015183820152602001610cf6565b50505050905090810190601f168015610d3b5780820380516001836020036101000a031916815260200191505b50858103825286518152865160209182019188019080838360005b83811015610d6e578181015183820152602001610d56565b50505050905090810190601f168015610d9b5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390f35b348015610dc257600080fd5b506103e260048036036020811015610dd957600080fd5b503561373e565b348015610dec57600080fd5b506103e260048036036020811015610e0357600080fd5b5035600160a060020a0316613750565b348015610e1f57600080fd5b506103e260048036036040811015610e3657600080fd5b50600160a060020a038135169060200135613762565b348015610e5857600080fd5b506103b660048036036040811015610e6f57600080fd5b50600160a060020a03813516906020013561377f565b348015610e9157600080fd5b506102d4613892565b348015610ea657600080fd5b5061042760048036036040811015610ebd57600080fd5b50600160a060020a0381351690602001356138a1565b348015610edf57600080fd5b506103e260048036036040811015610ef657600080fd5b50803590602001356138c1565b348015610f0f57600080fd5b506102d46138de565b348015610f2457600080fd5b506103b660048036036020811015610f3b57600080fd5b5035600160a060020a03166138ed565b348015610f5757600080fd5b506103b66004803603610140811015610f6f57600080fd5b81359160ff6020820135169160408201359160608101359160808201359160a08101359160c08201359160e08101359161010082013591908101906101408101610120820135640100000000811115610fc757600080fd5b820183602082011115610fd957600080fd5b80359060200191846001830284011164010000000083111715610ffb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613aca945050505050565b34801561104857600080fd5b506103b66004803603604081101561105f57600080fd5b8135919081019060408101602082013564010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506140e3945050505050565b34801561110257600080fd5b506103e26004803603602081101561111957600080fd5b50356143ae565b34801561112c57600080fd5b506103e26143c0565b34801561114157600080fd5b506103b66004803603602081101561115857600080fd5b81019060208101813564010000000081111561117357600080fd5b82018360208201111561118557600080fd5b803590602001918460018302840111640100000000831117156111a757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506143c6945050505050565b3480156111f457600080fd5b506103b66004803603606081101561120b57600080fd5b81019060208101813564010000000081111561122657600080fd5b82018360208201111561123857600080fd5b8035906020019184600183028401116401000000008311171561125a57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156112ad57600080fd5b8201836020820111156112bf57600080fd5b803590602001918460018302840111640100000000831117156112e157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561133457600080fd5b82018360208201111561134657600080fd5b8035906020019184600183028401116401000000008311171561136857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061440b945050505050565b3480156113b557600080fd5b506103e2600480360360208110156113cc57600080fd5b5035600160a060020a031661447a565b3480156113e857600080fd5b506103b6600480360360208110156113ff57600080fd5b503561448c565b34801561141257600080fd5b506103b66004803603602081101561142957600080fd5b5035600160a060020a03166145cf565b34801561144557600080fd5b506103e26004803603602081101561145c57600080fd5b5035600160a060020a031661462a565b60008282018381101561147b57fe5b9392505050565b601e80548290811061149057fe5b600091825260209091200154600160a060020a0316905081565b60008211611528576040805160e560020a62461bcd02815260206004820152602160248201527f57616765722073686f756c642062652067726561746572207468616e207a657260448201527f6f00000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b336000908152601c602052604090205482111561158f576040805160e560020a62461bcd02815260206004820152601260248201527f4e6f7420656e6f7567682062616c616e63650000000000000000000000000000604482015290519081900360640190fd5b336000908152601660209081526040808320878452825280832086845290915290205415611653576040805160e560020a62461bcd02815260206004820152604860248201527f416c726561647920706c6163656420612062657420666f72207468697320666f60448201527f7265636173742c2075736520696e6372656173655761676572206d6574686f6460648201527f20696e7374656164000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b600080858152600d60205260409020600c015460a060020a900460ff16600281111561167b57fe5b14158061169657506000848152601160205260409020546001145b1515611712576040805160e560020a62461bcd02815260206004820152602860248201527f4865616420746f20686561642062657420686173206265656e20616c7265616460448201527f792063616c6c6564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000848152600d60205260409020600901548210156117a1576040805160e560020a62461bcd02815260206004820152602860248201527f5761676572206973206c6f776572207468616e20746865206d696e696d756d2060448201527f6163636570746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000848152600d60205260409020600a015415806117d057506000848152600d60205260409020600a01548211155b151561184c576040805160e560020a62461bcd02815260206004820152602960248201527f576167657220697320686967686572207468656e20746865206d6178696d756d60448201527f2061636365707465640000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6118558461463c565b6000848152600d602052604090206008015460ff16156118bf576040805160e560020a62461bcd02815260206004820152601660248201527f42657420686173206265656e2063616e63656c6c656400000000000000000000604482015290519081900360640190fd5b6000848152600d602052604090206005015460ff1615611929576040805160e560020a62461bcd02815260206004820152601c60248201527f4576656e742068617320616c726561647920616e206f7574636f6d6500000000604482015290519081900360640190fd5b6000848152600d6020526040902060060154421115611992576040805160e560020a62461bcd02815260206004820152601560248201527f436c6f73652074696d6520686173207061737365640000000000000000000000604482015290519081900360640190fd5b60008481526011602090815260408083208054600101905560109091528120805484019055600f80548401905560095411156119ef576119da826003600601546103e861494b565b60008581526020805260409020805490910190555b600a5460001015611a2257611a0c826003600701546103e861494b565b6000858152602160205260409020805490910190555b336000818152601c6020908152604080832080548790039055601582528083208884528252808320805460019081019091556013835281842088855283528184208054880190558484526014835281842089855283528184208054880190558484526016835281842089855283528184208885528352818420879055848452601a8352818420805482019055601b8352818420805488019055888452600d835292819020600601548151898152928301859052600080516020614a8c8339815191529489949093909288928a92899281018660ff16815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611b47578181015183820152602001611b2f565b50505050905090810190601f168015611b745780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a150505050565b602080526000908152604090205481565b600160a060020a03166000908152601a60205260408120541190565b33600090815260146020908152604080832085845290915281205411611c2a576040805160e560020a62461bcd02815260206004820152601c60248201527f43616c6c6572206861736e277420706c6163656420616e792062657400000000604482015290519081900360640190fd5b33600090815260186020908152604080832085845290915290205460ff1615611c9d576040805160e560020a62461bcd02815260206004820152600f60248201527f416c726561647920726566757465640000000000000000000000000000000000604482015290519081900360640190fd5b611ca68261463c565b6000828152600d602052604090206005015460ff161515611d37576040805160e560020a62461bcd02815260206004820152603160248201527f5265667574652069736e277420616c6c6f776564207768656e206e6f206f757460448201527f636f6d6520686173206265656e20736574000000000000000000000000000000606482015290519081900360840190fd5b6000828152600d60205260409020600701544210611dc5576040805160e560020a62461bcd02815260206004820152603160248201527f5265667574652069736e277420616c6c6f776564207768656e204576656e742060448201527f667265657a652068617320706173736564000000000000000000000000000000606482015290519081900360840190fd5b3360008181526018602090815260408083208684528252808320805460ff1916600117905592825260148152828220858352815282822054601280835284842080549092019182905560108352939092205492905210611e3c576000828152600d60205260409020600801805460ff191660011790555b600080516020614a8c8339815191528233600360008086600d60008a8152602001908152602001600020600601546040518088815260200187600160a060020a0316600160a060020a03168152602001866007811115611e9857fe5b60ff16815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611eeb578181015183820152602001611ed3565b50505050905090810190601f168015611f185780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a15050565b60225481565b3360009081526014602090815260408083208684529091528120548110611fa6576040805160e560020a62461bcd02815260206004820152601c60248201527f43616c6c6572206861736e277420706c6163656420616e792062657400000000604482015290519081900360640190fd5b8215611fcd575033600090815260146020908152604080832086845290915290205461147b565b6000848152601360209081526040808320858452909152812054111561205757600084815260216020908152604080832054828052818420546010845282852054338652601685528386208a875285528386208887528552838620548a875260138652848720898852909552929094205493909103039161204f91839161494b565b91505061147b565b336000908152601460209081526040808320878452909152902054600a5461208291906103e861494b565b3360009081526014602090815260408083208884529091529020546009546120ad91906103e861494b565b336000908152601460209081526040808320898452909152902054030390509392505050565b601f6020526000908152604090205460ff1681565b600d60205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0154600a8b0154600b8c0154600c909c01549a9b600160a060020a039a8b169b999a9899979860ff9788169896979596948616959394929391929081169160a060020a909104168e565b336000908152601460209081526040808320858452909152812054116121dd576040805160e560020a62461bcd02815260206004820152601c60248201527f43616c6c6572206861736e277420706c6163656420616e792062657400000000604482015290519081900360640190fd5b33600090815260196020908152604080832085845290915290205460ff1615612250576040805160e560020a62461bcd02815260206004820152600f60248201527f416c726561647920736574746c65640000000000000000000000000000000000604482015290519081900360640190fd5b6122598261463c565b6000828152600d602052604090206008015460ff168061228a57506000828152600d602052604090206005015460ff165b1515612306576040805160e560020a62461bcd02815260206004820152602960248201527f4265742073686f756c642062652063616e63656c6c6564206f7220686173206160448201527f6e206f7574636f6d650000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000828152600d602052604090206007015442101561236f576040805160e560020a62461bcd02815260206004820152601860248201527f426574207061796d656e74732061726520667265657a65640000000000000000604482015290519081900360640190fd5b6000828152600d602052604081206008015460ff16156123d5575060008281526020808052604080832083905560218252808320839055338084526014835281842086855283528184205490845260178352818420868552909252909120556005612743565b6000838152601f602052604090205460ff161580156123ff57506000838152602080526040812054115b156124c25760005b601e548110156124a9576000848152602080526040812054601e805461246393601d9290918690811061243657fe5b6000918252602080832090910154600160a060020a031683528201929092526040019020546103e861494b565b601c6000601e8481548110151561247657fe5b6000918252602080832090910154600160a060020a03168352820192909252604001902080549091019055600101612407565b5060008381526020805260409020546022805490910190555b6000838152601f602052604090205460ff161580156124ed5750600083815260216020526040812054115b156125d9576000838152600d602090815260408083206001015481517f8da5cb5b0000000000000000000000000000000000000000000000000000000081529151600160a060020a0390911692638da5cb5b9260048082019391829003018186803b15801561255b57600080fd5b505afa15801561256f573d6000803e3d6000fd5b505050506040513d602081101561258557600080fd5b505160008581526021602090815260408083208054600160a060020a039586168552601c84528285208054909101905588845254600d83528184206001015490941683526023909152902080549091019055505b6000838152601360209081526040808320600d8352818420600401548452909152812054111561269157600083815260216020908152604080832054828052818420546010845282852054338652601685528386208987528552838620600d865284872060040154808852908652848720548a8852601387528588209188529552929094205493909103039161267091839161494b565b3360009081526017602090815260408083208884529091529020555061271e565b336000908152601460209081526040808320868452909152902054600a546126bc91906103e861494b565b3360009081526014602090815260408083208784529091529020546009546126e791906103e861494b565b3360008181526014602090815260408083208984528252808320549383526017825280832089845290915290209190039190910390555b3360009081526017602090815260408083208684529091528120541115612743575060045b6000838152601f602090815260408083208054600160ff19918216811790925533808652601985528386208987528552838620805490921690921790558084526017835281842087855283528184208054828652601c85528386208054909101905587855254600d8452828520600601548351898152948501839052600080516020614a8c8339815191529589959394889491928a92909181018660078111156127e957fe5b60ff16815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561283c578181015183820152602001612824565b50505050905090810190601f1680156128695780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a1505050565b3031811115612900576040805160e560020a62461bcd02815260206004820152603360248201527f496e73756666696369656e7420486f7573652062616c616e63652e2053686f7560448201527f6c646e277420686176652068617070656e656400000000000000000000000000606482015290519081900360840190fd5b336000908152601c6020526040902054811115612967576040805160e560020a62461bcd02815260206004820152601460248201527f496e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b336000908152601c60205260409020546129819082614968565b336000818152601c6020526040808220939093559151909183156108fc02918491818181858888f193505050501580156129bf573d6000803e3d6000fd5b506040805182815260006020820152815133927fe1ad1162eeaaa41101454531343fcf2c339a2e59af62648980c06bd7e3f333e2928290030190a250565b601560209081526000928352604080842090915290825290205481565b600054600160a060020a03163314612a3157600080fd5b6000818152600d60205260409020600701544210612a99576040805160e560020a62461bcd02815260206004820152601260248201527f467265657a652074696d65207061737365640000000000000000000000000000604482015290519081900360640190fd5b60035460ff161515612b1b576040805160e560020a62461bcd02815260206004820152602260248201527f43616e63656c20617661696c61626c65206f6e206d616e6167656420486f757360448201527f6573000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000818152600d6020908152604080832060088101805460ff191660011790556006015481518581523393810193909352600783830152606083018490526080830184905260c083015260e060a083018190528201929092529051600080516020614a8c83398151915291610120908290030190a150565b3031811115612ba157600080fd5b336000908152601c6020526040902054811115612c08576040805160e560020a62461bcd02815260206004820152601460248201527f496e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b336000908152601c6020526040902054612c229082614968565b336000908152601c6020526040808220929092559051600160a060020a0384169183156108fc02918491818181858888f19350505050158015612c69573d6000803e3d6000fd5b506040805182815260006020820152815133927fe1ad1162eeaaa41101454531343fcf2c339a2e59af62648980c06bd7e3f333e2928290030190a25050565b601d6020526000908152604090205481565b601860209081526000928352604080842090915290825290205460ff1681565b600054600160a060020a03163314612cf157600080fd5b8051612d0490600c9060208401906149d3565b506008805474ff000000000000000000000000000000000000000019169055604051600080516020614a6c83398151915290600090a150565b600f5481565b60008211612dc1576040805160e560020a62461bcd02815260206004820152603160248201527f496e63726561736520776167657220616d6f756e742073686f756c642062652060448201527f67726561746572207468616e207a65726f000000000000000000000000000000606482015290519081900360840190fd5b336000908152601c6020526040902054821115612e28576040805160e560020a62461bcd02815260206004820152601260248201527f4e6f7420656e6f7567682062616c616e63650000000000000000000000000000604482015290519081900360640190fd5b336000908152601660209081526040808320878452825280832086845290915281205411612ec6576040805160e560020a62461bcd02815260206004820152603d60248201527f486176656e277420706c6163656420616e792062657420666f7220746869732060448201527f666f7265636173742e205573652063616c6c42657420696e7374656164000000606482015290519081900360840190fd5b600080858152600d60205260409020600c015460a060020a900460ff166002811115612eee57fe5b141580612f0957506000848152601160205260409020546001145b1515612f85576040805160e560020a62461bcd02815260206004820152602860248201527f4865616420746f20686561642062657420686173206265656e20616c7265616460448201527f792063616c6c6564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b3360009081526016602090815260408083208784528252808320868452825280832054878452600d909252909120600a0154908301901580612fd857506000858152600d60205260409020600a01548111155b1515613054576040805160e560020a62461bcd02815260206004820152603560248201527f546865207570646174656420776167657220697320686967686572207468656e60448201527f20746865206d6178696d756d2061636365707465640000000000000000000000606482015290519081900360840190fd5b61305d8561463c565b6000858152600d602052604090206008015460ff16156130c7576040805160e560020a62461bcd02815260206004820152601660248201527f42657420686173206265656e2063616e63656c6c656400000000000000000000604482015290519081900360640190fd5b6000858152600d602052604090206005015460ff1615613131576040805160e560020a62461bcd02815260206004820152601c60248201527f4576656e742068617320616c726561647920616e206f7574636f6d6500000000604482015290519081900360640190fd5b6000858152600d602052604090206006015442111561319a576040805160e560020a62461bcd02815260206004820152601560248201527f436c6f73652074696d6520686173207061737365640000000000000000000000604482015290519081900360640190fd5b6000858152601060205260408120805485019055600f80548501905560095411156131e6576131d1836003600601546103e861494b565b60008681526020805260409020805490910190555b600a546000101561321957613203836003600701546103e861494b565b6000868152602160205260409020805490910190555b336000818152601c60209081526040808320805488900390558883526013825280832088845282528083208054880190558383526014825280832089845282528083208054880190558383526016825280832089845282528083208884528252808320805488019055838352601b8252808320805488019055888352600d82529182902060069081015483518a8152928301859052600080516020614a8c833981519152948a94909389928b928a929081018660ff16815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561331f578181015183820152602001613307565b50505050905090810190601f16801561334c5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a15050505050565b60116020526000908152604090205481565b601660209081526000938452604080852082529284528284209052825290205481565b60015b90565b601a6020526000908152604090205481565b600054600160a060020a031633146133ca57600080fd5b6002805473ffffffffffffffffffffffffffffffffffffffff191690556008805474ff000000000000000000000000000000000000000019169055604051600080516020614a6c83398151915290600090a1565b60216020526000908152604090205481565b601460209081526000928352604080842090915290825290205481565b600054600160a060020a0316331461346457600080fd5b805161347790600c9060208401906149d3565b506008805474ff0000000000000000000000000000000000000000191660a060020a179055604051600080516020614a6c83398151915290600090a150565b600380546004805460408051602060026101006001861615026000190190941693909304601f810184900484028201840190925281815260ff909416949392918301828280156135475780601f1061351c57610100808354040283529160200191613547565b820191906000526020600020905b81548152906001019060200180831161352a57829003601f168201915b50505060028085018054604080516020601f60001961010060018716150201909416959095049283018590048502810185019091528181529596959450909250908301828280156135d95780601f106135ae576101008083540402835291602001916135d9565b820191906000526020600020905b8154815290600101906020018083116135bc57829003601f168201915b5050505060038301805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529495949350908301828280156136695780601f1061363e57610100808354040283529160200191613669565b820191906000526020600020905b81548152906001019060200180831161364c57829003601f168201915b505050506004830154600584015460068501546007860154600887015460098801805460408051602060026101006001861615026000190190941693909304601f8101849004840282018401909252818152999a600160a060020a039889169a988816995060a060020a90970460ff16979596949593949392918301828280156137345780601f1061370957610100808354040283529160200191613734565b820191906000526020600020905b81548152906001019060200180831161371757829003601f168201915b505050505090508b565b60126020526000908152604090205481565b60236020526000908152604090205481565b601760209081526000928352604080842090915290825290205481565b600054600160a060020a0316331461379657600080fd5b6103e86137a86003600601548361146c565b10613823576040805160e560020a62461bcd02815260206004820152603360248201527f486f757365202b204f7261636c652070657263656e746167652073686f756c6460448201527f206265206c6f776572207468616e203130302500000000000000000000000000606482015290519081900360840190fd5b600754600160a060020a03838116911614613872576007805460088054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff19928316179092559091169084161790555b600a819055604051600080516020614a6c83398151915290600090a15050565b600254600160a060020a031681565b601960209081526000928352604080842090915290825290205460ff1681565b601360209081526000928352604080842090915290825290205481565b600054600160a060020a031681565b600054600160a060020a0316331461390457600080fd5b600160a060020a038116301415613965576040805160e560020a62461bcd02815260206004820152601e60248201527f4e657720616464726573732069732063757272656e7420616464726573730000604482015290519081900360640190fd5b80600160a060020a0316636369313d6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156139ba57600080fd5b505afa1580156139ce573d6000803e3d6000fd5b505050506040513d60208110156139e457600080fd5b50511515613a62576040805160e560020a62461bcd02815260206004820152602c60248201527f4e657720616464726573732073686f756c64206265206120486f75736520736d60448201527f61727420636f6e74726163740000000000000000000000000000000000000000606482015290519081900360840190fd5b60028054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff199091161790556008805474ff0000000000000000000000000000000000000000191660a060020a179055604051600080516020614a6c83398151915290600090a150565b60008611613b48576040805160e560020a62461bcd02815260206004820152602160248201527f57616765722073686f756c642062652067726561746572207468616e207a657260448201527f6f00000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b336000908152601c6020526040902054861115613baf576040805160e560020a62461bcd02815260206004820152601260248201527f4e6f7420656e6f7567682062616c616e63650000000000000000000000000000604482015290519081900360640190fd5b60085460a060020a900460ff1615613c11576040805160e560020a62461bcd02815260206004820152601960248201527f426574732061726520706175736564207269676874206e6f7700000000000000604482015290519081900360640190fd5b6001805481018082556000818152600d6020526040808220928355600754928401805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0390941693909317909255825481528181206003018b90558254815281812060029081018e90559254815220600c0180548b9274ff0000000000000000000000000000000000000000199091169060a060020a908490811115613cb157fe5b0217905550600180546000908152600d60205260409020600c01805473ffffffffffffffffffffffffffffffffffffffff19163317905554613cf29061463c565b6001546000908152600d602052604090206008015460ff1615613d5f576040805160e560020a62461bcd02815260206004820152601860248201527f4576656e7420686173206265656e2063616e63656c6c65640000000000000000604482015290519081900360640190fd5b6001546000908152600d602052604090206005015460ff1615613dcc576040805160e560020a62461bcd02815260206004820152601c60248201527f4576656e742068617320616c726561647920616e206f7574636f6d6500000000604482015290519081900360640190fd5b6000851115613ded576001546000908152600d602052604090206006018590555b6001546000908152600d6020526040902060060154421115613e59576040805160e560020a62461bcd02815260206004820152601560248201527f436c6f73652074696d6520686173207061737365640000000000000000000000604482015290519081900360640190fd5b8315613e7b576001546000908152600d60205260409020600901849055613e93565b6001546000908152600d602052604090206009018690555b8215613eb1576001546000908152600d60205260409020600a018390555b8115613ecf576001546000908152600d60205260409020600b018290555b33600090815260156020908152604080832060018054855290835281842081905580548452601183528184208190558054845260109092528220889055600e80549091019055600f8054880190556009541115613f5057613f38866003600601546103e861494b565b60015460009081526020805260409020805490910190555b600a5460001015613f8657613f6d866003600701546103e861494b565b6001546000908152602160205260409020805490910190555b336000818152601c6020908152604080832080548b90039055600180548452601383528184208c855283528184208b9055848452601483528184208154855283528184208b9055848452601683528184208154855283528184208c855283528184208b9055848452601a8352818420805482019055601b835281842080548c01905554808452600d8352818420600601548251828152938401869052600080516020614a8c833981519152959194919391928c928e92899290919081018660ff16815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561409757818101518382015260200161407f565b50505050905090810190601f1680156140c45780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a150505050505050505050565b6000828152600d60205260409020600c0154600160a060020a0316331461417a576040805160e560020a62461bcd02815260206004820152602560248201527f43616c6c657220616e6420706c61796572206372656174656420646f6e27742060448201527f6d61746368000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b33600090815260156020908152604080832085845290915281205411614210576040805160e560020a62461bcd02815260206004820152602960248201527f506c617965722073686f756c642068617320706c61636564206174206c65617360448201527f74206f6e65206265740000000000000000000000000000000000000000000000606482015290519081900360840190fd5b336000908152601560209081526040808320858452825280832054601190925290912054146142af576040805160e560020a62461bcd02815260206004820152602760248201527f5468652062657420686173206265656e2063616c6c6564206279206f7468657260448201527f20706c6179657200000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6142b88261463c565b6000828152600d6020818152604080842060088101805460ff191660011790556010835281852080546011855283872087905590869055338087526015855283872089885285528387208054600e8054919091039055600f8054849003905585805284882088905560218652848820889055818852601c8652848820805484019055601486528488208a895286528488208890558054828952601a87528589208054919091039055601b86528488208054849003905589885287905594845260069091015482518881529384018590529094600080516020614a8c83398151915294889490936002938893928a928101866127e9565b60106020526000908152604090205481565b600e5481565b600054600160a060020a031633146143dd57600080fd5b80516143f090600c9060208401906149d3565b50604051600080516020614a6c83398151915290600090a150565b600054600160a060020a0316331461442257600080fd5b82516144359060049060208601906149d3565b5081516144499060059060208501906149d3565b50805161445d9060069060208401906149d3565b50604051600080516020614a6c83398151915290600090a1505050565b601c6020526000908152604090205481565b600054600160a060020a031633146144a357600080fd5b600954811415614523576040805160e560020a62461bcd02815260206004820152602860248201527f4e65772070657263656e74616765206973206964656e746963616c207769746860448201527f2063757272656e74000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6103e86145358260036007015461146c565b106145b0576040805160e560020a62461bcd02815260206004820152603360248201527f486f757365202b204f7261636c652070657263656e746167652073686f756c6460448201527f206265206c6f776572207468616e203130302500000000000000000000000000606482015290519081900360840190fd5b6009819055604051600080516020614a6c83398151915290600090a150565b600054600160a060020a031633146145e657600080fd5b600160a060020a03811615156145fb57600080fd5b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b601b6020526000908152604090205481565b6000818152600d602052604090206005015460ff1615156147f6576000818152600d60209081526040918290206001810154600282015460039092015484517fc49c3635000000000000000000000000000000000000000000000000000000008152600481019390935260248301529251600160a060020a039093169263c49c363592604480840193919291829003018186803b1580156146dc57600080fd5b505afa1580156146f0573d6000803e3d6000fd5b505050506040513d602081101561470657600080fd5b50516000828152600d60205260409020600501805460ff1916911515919091179081905560ff16156147f6576000818152600d60209081526040918290206001810154600282015460039092015484517f0937fb36000000000000000000000000000000000000000000000000000000008152600481019390935260248301529251600160a060020a0390931692630937fb3692604480840193919291829003018186803b1580156147b757600080fd5b505afa1580156147cb573d6000803e3d6000fd5b505050506040513d60208110156147e157600080fd5b50516000828152600d60205260409020600401555b6000818152600d602052604090206008015460ff1615156148f3576000818152600d602052604090819020600181015460029091015482517f7599609d00000000000000000000000000000000000000000000000000000000815260048101919091529151600160a060020a0390911691637599609d916024808301926060929190829003018186803b15801561488c57600080fd5b505afa1580156148a0573d6000803e3d6000fd5b505050506040513d60608110156148b657600080fd5b5080516020808301516040938401516000868152600d9093529390912060088101805460ff19169415159490941790935560078301556006909101555b6000818152600d602052604090206005015460ff1615801561492657506000818152600d60205260409020600701544210155b15614948576000818152600d60205260409020600801805460ff191660011790555b50565b600061496061495a858561497a565b8361499e565b949350505050565b60008282111561497457fe5b50900390565b6000828202831580614996575082848281151561499357fe5b04145b151561147b57fe5b60008115156149a957fe5b600082848115156149b657fe5b04905082848115156149c457fe5b06818402018414151561147b57fe5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614a1457805160ff1916838001178555614a41565b82800160010185558215614a41579182015b82811115614a41578251825591602001919060010190614a26565b50614a4d929150614a51565b5090565b61339e91905b80821115614a4d5760008155600101614a5756fe320e86f1a131f064553e23750e49d1c875514b81dc87c91e4e8d55ed3579575d7067884a733b94f86d176e3aa932e4b029667a0927468771fa6fbf21b18ebcbaa165627a7a723058208c12ff1c194ead5e10aacd7643e794a827e9c413685516ee7c3b9644c74bd9c70029";
    let extractor = common::new_extractor_from_bytecode(bytecode, LazyWatchdog.in_rc())?;

    // Get the final storage layout for the input contract
    let layout = extractor.analyze()?;

    // We should see 36 entries
    assert_eq!(layout.slot_count(), 36);

    // `address` but we infer `number160`
    assert!(layout.has_slot(0, 0, AbiType::Number { size: Some(160) }));

    // `uint256` but we infer `number256`
    assert!(layout.has_slot(1, 0, AbiType::Number { size: Some(256) }));

    // `address`
    assert!(layout.has_slot(2, 0, AbiType::Address));

    // `bool` but we infer `number8`
    assert!(layout.has_slot(3, 0, AbiType::Number { size: Some(8) }));

    // `string` but we infer `bytes`
    assert!(layout.has_slot(4, 0, AbiType::DynBytes));

    // `string` but we infer `bytes`
    assert!(layout.has_slot(5, 0, AbiType::DynBytes));

    // `string` but we infer `bytes`
    assert!(layout.has_slot(6, 0, AbiType::DynBytes));

    // `address`
    assert!(layout.has_slot(7, 0, AbiType::Address));

    // `packed(address, bool)` but we infer `packed(address, number8)`
    assert!(layout.has_slot(8, 0, AbiType::Address));
    assert!(layout.has_slot(8, 160, AbiType::Number { size: Some(8) }));

    // `uint256`
    assert!(layout.has_slot(9, 0, AbiType::UInt { size: Some(256) }));

    // `uint256`
    assert!(layout.has_slot(10, 0, AbiType::UInt { size: Some(256) }));

    // `uint256` but we miss it entirely
    assert!(layout.has_no_slot_at(11));

    // `string` but we infer `bytes`
    assert!(layout.has_slot(12, 0, AbiType::DynBytes));

    // `mapping(uint256 => struct)` but we infer `mapping(number256 => struct)` but
    // the struct is not quite the same
    assert!(layout.has_slot(
        13,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Number { size: Some(256) }),
            value_type: Box::new(AbiType::Struct {
                elements: vec![
                    StructElement::new(0, AbiType::Number { size: Some(256) }),
                    StructElement::new(256, AbiType::Address),
                    StructElement::new(416, AbiType::Number { size: Some(8) }),
                    StructElement::new(512, AbiType::Bytes { length: Some(32) }),
                    StructElement::new(768, AbiType::Bytes { length: Some(32) }),
                    StructElement::new(1024, AbiType::Bytes { length: Some(32) }),
                    StructElement::new(1280, AbiType::Number { size: Some(8) }),
                    StructElement::new(1288, AbiType::Bytes { length: Some(31) }),
                    StructElement::new(1536, AbiType::UInt { size: Some(256) }),
                    StructElement::new(1792, AbiType::UInt { size: None }),
                    StructElement::new(2048, AbiType::Number { size: Some(8) }),
                    StructElement::new(2056, AbiType::Bytes { length: Some(31) }),
                    StructElement::new(2304, AbiType::UInt { size: Some(256) }),
                    StructElement::new(2560, AbiType::UInt { size: Some(256) }),
                    StructElement::new(2816, AbiType::Number { size: Some(256) }),
                    StructElement::new(3072, AbiType::Bytes { length: Some(20) }),
                    StructElement::new(3232, AbiType::Bytes { length: Some(1) }),
                    StructElement::new(3240, AbiType::Any),
                ],
            }),
        }
    ));

    // `uint256` but we infer `numberUnknown`
    assert!(layout.has_slot(14, 0, AbiType::Number { size: None }));

    // `uint256` but we infer `numberUnknown`
    assert!(layout.has_slot(15, 0, AbiType::Number { size: None }));

    // `mapping(uint256 => uint256)` but we infer `mapping(number256 => uint256)`
    assert!(layout.has_slot(
        16,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Number { size: Some(256) }),
            value_type: Box::new(AbiType::UInt { size: Some(256) }),
        }
    ));

    // `mapping(uint256 => uint256)` but we infer `mapping(number256 =>
    // numberUnknown)`
    assert!(layout.has_slot(
        17,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Number { size: Some(256) }),
            value_type: Box::new(AbiType::Number { size: None }),
        }
    ));

    // `mapping(uint256 => uint256)` but we infer `mapping(number256 =>
    // uintUnknown)`
    assert!(layout.has_slot(
        18,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Number { size: Some(256) }),
            value_type: Box::new(AbiType::UInt { size: None }),
        }
    ));

    // `mapping(uint256 => mapping(uint256 => uint256))` but we infer
    // `mapping(number256 => mapping(bytes32 => uint256))`
    assert!(layout.has_slot(
        19,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Number { size: Some(256) }),
            value_type: Box::new(AbiType::Mapping {
                key_type:   Box::new(AbiType::Bytes { length: Some(32) }),
                value_type: Box::new(AbiType::UInt { size: Some(256) }),
            }),
        }
    ));

    // `mapping(address => mapping(uint256 => uint256))` but we infer
    // `mapping(address => mapping(number256 => uint256))`
    assert!(layout.has_slot(
        20,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::Mapping {
                key_type:   Box::new(AbiType::Number { size: Some(256) }),
                value_type: Box::new(AbiType::UInt { size: Some(256) }),
            }),
        }
    ));

    // `mapping(address => mapping(uint256 => uint256))` but we infer
    // `mapping(address => mapping(number256 => uintUnknown))`
    assert!(layout.has_slot(
        21,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::Mapping {
                key_type:   Box::new(AbiType::Number { size: Some(256) }),
                value_type: Box::new(AbiType::UInt { size: None }),
            }),
        }
    ));

    // `mapping(address => mapping(uint256 => mapping(uint256 => uint256)))` but we
    // infer `mapping(address => mapping(number256 => mapping(bytes32 => uint256))`
    assert!(layout.has_slot(
        22,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::Mapping {
                key_type:   Box::new(AbiType::Number { size: Some(256) }),
                value_type: Box::new(AbiType::Mapping {
                    key_type:   Box::new(AbiType::Bytes { length: Some(32) }),
                    value_type: Box::new(AbiType::UInt { size: Some(256) }),
                }),
            }),
        }
    ));

    // `mapping(address => mapping(uint256 => uint256))` but we infer
    // `mapping(address => mapping(number256 => uint256))`
    assert!(layout.has_slot(
        23,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::Mapping {
                key_type:   Box::new(AbiType::Number { size: Some(256) }),
                value_type: Box::new(AbiType::UInt { size: Some(256) }),
            }),
        }
    ));

    // `mapping(address => mapping(uint256 => uint256))` but we infer
    // `mapping(address => mapping(number256 => struct(number8, bytes31)))`
    assert!(layout.has_slot(
        24,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::Mapping {
                key_type:   Box::new(AbiType::Number { size: Some(256) }),
                value_type: Box::new(AbiType::Struct {
                    elements: vec![
                        StructElement::new(0, AbiType::Number { size: Some(8) }),
                        StructElement::new(8, AbiType::Bytes { length: Some(31) })
                    ],
                }),
            }),
        }
    ));

    // `mapping(address => mapping(uint256 => bool))` but we infer
    // `mapping(address => mapping(number256 => struct(number8, bytes31)))`
    assert!(layout.has_slot(
        25,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::Mapping {
                key_type:   Box::new(AbiType::Number { size: Some(256) }),
                value_type: Box::new(AbiType::Struct {
                    elements: vec![
                        StructElement::new(0, AbiType::Number { size: Some(8) }),
                        StructElement::new(8, AbiType::Bytes { length: Some(31) })
                    ],
                }),
            }),
        }
    ));

    // `mapping(address => uint256)` but we infer `mapping(address => uintUnknown)`
    assert!(layout.has_slot(
        26,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::UInt { size: None }),
        }
    ));

    // `mapping(address => uint256)` but we infer `mapping(address =>
    // numberUnknown)`
    assert!(layout.has_slot(
        27,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::Number { size: None }),
        }
    ));

    // `mapping(address => uint256)` but we infer `mapping(address => uintUnknown)`
    assert!(layout.has_slot(
        28,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::UInt { size: None }),
        }
    ));

    // `mapping(address => uint256)` but we infer `mapping(bytes20 => numberNone)`
    assert!(layout.has_slot(
        29,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Bytes { length: Some(20) }),
            value_type: Box::new(AbiType::Number { size: None }),
        }
    ));

    // `address[]` but we infer `bytes20[]`
    assert!(layout.has_slot(
        30,
        0,
        AbiType::DynArray {
            tp: Box::new(AbiType::Bytes { length: Some(20) }),
        }
    ));

    // `mapping(uint256 => bool)` but we infer `mapping(number256 => struct(number8,
    // bytes31))`
    assert!(layout.has_slot(
        31,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Number { size: Some(256) }),
            value_type: Box::new(AbiType::Struct {
                elements: vec![
                    StructElement::new(0, AbiType::Number { size: Some(8) }),
                    StructElement::new(8, AbiType::Bytes { length: Some(31) })
                ],
            }),
        }
    ));

    // `mapping(uint256 => uint256)` but we infer `mapping(number256 =>
    // uintUnknown)`
    assert!(layout.has_slot(
        32,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Number { size: Some(256) }),
            value_type: Box::new(AbiType::UInt { size: None }),
        }
    ));

    // `mapping(uint256 => uint256)` but we infer `mapping(number256 =>
    // uintUnknown)`
    assert!(layout.has_slot(
        33,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Number { size: Some(256) }),
            value_type: Box::new(AbiType::UInt { size: None }),
        }
    ));

    // `uint256` but we infer `numberUnknown`
    assert!(layout.has_slot(34, 0, AbiType::Number { size: None }));

    // `mapping(address => uint256)` but we infer `mapping(address =>
    // numberUnknown)`
    assert!(layout.has_slot(
        35,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Address),
            value_type: Box::new(AbiType::Number { size: None }),
        }
    ));

    Ok(())
}
