It's great to be here...
The talks are from 40 to 90 minutes long, including question time.
Overall Goal: Demonstate a technique for showing the correctness of smart contracts
Overview:
Introduction to theorem-proving in Coq
Example: Even and odd numbers
Definition Even (n : nat) := exists k, n = 2 * k. Definition Odd (m : nat) := exists l, m = 2 * l + 1.forall n : nat, Even n -> Odd (n + 1)forall n : nat, Even n -> Odd (n + 1)n: nat
H: Even nOdd (n + 1)n: nat
H: exists k : nat, n = 2 * kOdd (n + 1)n, k: nat
H: n = 2 * kOdd (n + 1)n, k: nat
H: n = 2 * kexists l : nat, n + 1 = 2 * l + 1n, k: nat
H: n = 2 * kn + 1 = 2 * k + 1reflexivity. Qed.n, k: nat
H: n = 2 * kn + 1 = n + 1
Introduction to creating a DeepSEA smart contract
Example: Trivial contract converting bool to int
object signature trivial = { const boolToInt : bool -> int } object Trivial : trivial { let boolToInt b = if b then 1 else 0 } layer CONTRACT = { o = Trivial }
object signature trivial = { const boolToInt : bool -> int; boolToIntTracker : bool -> int } object Trivial : trivial { let seenTrueYet : bool := false let boolToInt b = if b then 1 else 0 let boolToIntTracker b = if b then begin seenTrueYet := true; 1 end else 0 } layer CONTRACT = { o = Trivial }
$ dsc trivial.ds bytecode 5b60005b60206109205101610920525b61022660006020610920510301525b60006020 610920510301516101005260206101002060006020610920510301525b600060006020 61092051030151555b60206109205103610920525b60005b9050386300000073600039 386000f35b60006000fd5b610940610920527c01000000000000000000000000000000 000000000000000000000000006000350480635192f3c01463000000495780631e01e7 071463000000965760006000fd5b6004355b60006109205101610920525b8063000000 67576300000085565b600190505b60006109205103610920525b805b90506000526020 6000f35b60009050630000006c565b60006000fd5b6004355b60206109205101610920 525b8063000000b4576300000111565b61022660006020610920510301525b60006020 610920510301516101005260206101002060006020610920510301525b600160006020 61092051030151555b600190505b60206109205103610920525b805b90506000526020 6000f35b6000905063000000f8565b60006000fd
$ dsc trivial.ds abi
[ {"type":"constructor", "name":"constructor", "inputs":[], "outputs":[], "payable":false, "constant":false, "stateMutability":"nonpayable"}, {"type":"function", "name":"boolToInt", "inputs":[{"name":"b", "type":"bool"}], "outputs":[{"name":"", "type":"uint256"}], "payable":false, "constant":true, "stateMutability":"view"}, {"type":"function", "name":"boolToIntTracker", "inputs":[{"name":"b", "type":"bool"}], "outputs":[{"name":"", "type":"uint256"}], "payable":true, "constant":false, "stateMutability":"payable"}]
Next slide is a reminder of the contract definition.
object signature trivial = { const boolToInt : bool -> int; boolToIntTracker : bool -> int } object Trivial : trivial { let seenTrueYet : bool := false let boolToInt b = if b then 1 else 0 let boolToIntTracker b = if b then begin seenTrueYet := true; 1 end else 0 } layer CONTRACT = { o = Trivial }
$ dsc trivial.ds coq ...
if f then ret 1 else ret 0
$ dsc trivial.ds coq ...
if f then MonadState.modify (update_Trivial_seenTrueYet true) ;; ret 1 else ret 0
contract_address: addr
memModelOps: MemoryModelOps mem
forall (input : bool) (context : CallContext)
(before : BlockchainState) (result : Z32) (after : GetHighData),
let machine_environment :=
make_machine_env contract_address before context
(fun (_ : option global_abstract_data_type) (_ _ : addr)
(_ : wei) => true) in
runStateT (Trivial_boolToInt_opt input machine_environment)
(contract_state before) = Some (result, after) ->
result = 1 <-> input = true
Main goal:
result = 1 <-> input = true
contract_address: addrforall (input : bool) (context : CallContext) (before : BlockchainState) (result : Z32) (after : GetHighData), let machine_environment := make_machine_env contract_address before context (fun (_ : option global_abstract_data_type) (_ _ : addr) (_ : wei) => true) in runStateT (Trivial_boolToInt_opt input machine_environment) (contract_state before) = Some (result, after) -> result = 1 <-> input = truecontract_address: addr
input: bool
context: CallContext
before: BlockchainState
result: Z32
after: GetHighData
H: runStateT (Trivial_boolToInt_opt input machine_environment) (contract_state before) = Some (result, after)result = 1 <-> input = trueH: runStateT (Trivial_boolToInt_opt input machine_environment) (contract_state before) = Some (result, after)result = 1 <-> input = trueH: runStateT (if input then ret 1 else ret 0) (contract_state before) = Some (result, after)result = 1 <-> input = trueinput = trueresult = 1H: runStateT (if input then ret 1 else ret 0) (contract_state before) = Some (result, after)
H0: result = 1input = trueHeqb: input = true
H0: result = 1
H1: 1 = result
H2: contract_state before = aftertrue = trueHeqb: input = false
H0: result = 1
H1: 0 = result
H2: contract_state before = afterfalse = truereflexivity.Heqb: input = true
H0: result = 1
H1: 1 = result
H2: contract_state before = aftertrue = trueHeqb: input = false
H0: result = 1
H1: 0 = result
H2: contract_state before = afterfalse = truediscriminate.H1: 0 = 1false = trueH: runStateT (if input then ret 1 else ret 0) (contract_state before) = Some (result, after)
H0: input = trueresult = 1Heqb: input = true
H0: true = true
H1: 1 = result
H2: contract_state before = afterresult = 1Heqb: input = false
H0: false = true
H1: 0 = result
H2: contract_state before = afterresult = 1Heqb: input = true
H0: true = true
H1: 1 = result
H2: contract_state before = afterresult = 1reflexivity.H0: true = true1 = 1discriminate. Qed.Heqb: input = false
H0: false = true
H1: 0 = result
H2: contract_state before = afterresult = 1
Remember to click the extra button to show hypotheses for both goals when they are there.
Note that some hypothesis are hidden in the visualisations for clarity.
Next slide has a copy of the contract definition.
object signature trivial = { const boolToInt : bool -> int; boolToIntTracker : bool -> int } object Trivial : trivial { let seenTrueYet : bool := false let boolToInt b = if b then 1 else 0 let boolToIntTracker b = if b then begin seenTrueYet := true; 1 end else 0 } layer CONTRACT = { o = Trivial }
contract_address: addrforall (input : bool) (context : CallContext) (before : BlockchainState) (result : Z32) (after : GetHighData), let machine_environment := make_machine_env contract_address before context (fun (_ : option global_abstract_data_type) (_ _ : addr) (_ : wei) => true) in runStateT (Trivial_boolToIntTracker_opt input machine_environment) (contract_state before) = Some (result, after) -> result = 1 <-> input = truecontract_address: addrforall (input : bool) (context : CallContext) (before : BlockchainState) (result : Z32) (after : GetHighData), let machine_environment := make_machine_env contract_address before context (fun (_ : option global_abstract_data_type) (_ _ : addr) (_ : wei) => true) in runStateT (Trivial_boolToIntTracker_opt input machine_environment) (contract_state before) = Some (result, after) -> result = 1 <-> input = truecontract_address: addr
input: bool
context: CallContext
before: BlockchainState
result: Z32
after: GetHighData
H: runStateT (Trivial_boolToIntTracker_opt input machine_environment) (contract_state before) = Some (result, after)result = 1 <-> input = trueH: runStateT (Trivial_boolToIntTracker_opt input machine_environment) (contract_state before) = Some (result, after)result = 1 <-> input = trueH: runStateT (if input then MonadState.modify (update_Trivial_seenTrueYet true);; ret 1 else ret 0) (contract_state before) = Some (result, after)result = 1 <-> input = trueinput = trueresult = 1H: runStateT (if input then MonadState.modify (update_Trivial_seenTrueYet true);; ret 1 else ret 0) (contract_state before) = Some (result, after)
H0: result = 1input = trueHeqb: input = true
H0: result = 1
H3: update_Trivial_seenTrueYet true (contract_state before) = m
H1: 1 = result
H4: m = aftertrue = trueHeqb: input = false
H0: result = 1
H1: 0 = resultfalse = truereflexivity.Heqb: input = true
H0: result = 1
H3: update_Trivial_seenTrueYet true (contract_state before) = m
H1: 1 = result
H4: m = aftertrue = trueHeqb: input = false
H0: result = 1
H1: 0 = result
H2: contract_state before = afterfalse = truediscriminate.H1: 0 = 1false = trueH: runStateT (if input then MonadState.modify (update_Trivial_seenTrueYet true);; ret 1 else ret 0) (contract_state before) = Some (result, after)
H0: input = trueresult = 1Heqb: input = true
H0: true = true
H3: update_Trivial_seenTrueYet true (contract_state before) = m
H1: 1 = result
H4: m = afterresult = 1Heqb: input = false
H0: false = true
H1: 0 = resultresult = 1Heqb: input = true
H0: true = true
H3: update_Trivial_seenTrueYet true (contract_state before) = m
H1: 1 = result
H4: m = afterresult = 1reflexivity.H0: true = true1 = 1discriminate. Qed.Heqb: input = false
H0: false = true
H1: 0 = result
H2: contract_state before = afterresult = 1
Definition since_as_long (Property1 : BlockchainState -> Prop) (Property2 : BlockchainState -> Prop) (PropertyAboutAction : Step -> Prop) := forall actions start finish helper, ReachableVia start finish helper actions -> Property1 start -> (forall act, List.In act actions -> PropertyAboutAction act) -> Property2 finish. Notation "Property2 `since` Property1 `as-long-as` PropertyAboutAction" := (since_as_long Property1 Property2 PropertyAboutAction) (at level 1).
snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> boolforall (user : addr) (amount : Z), (donation_recorded user amount) `since` donation_recorded user amount `as-long-as` (no_claims_from user)
snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> boolforall (user : addr) (amount : Z), (donation_recorded user amount) `since` donation_recorded user amount `as-long-as` (no_claims_from user)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> boolforall (user : addr) (amount : Z) (actions : list Step) (start finish : BlockchainState) (helper : Step), ReachableVia start finish helper actions -> donation_recorded user amount start -> (forall act : Step, In act actions -> no_claims_from user act) -> donation_recorded user amount finishsnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
actions: list Step
start, finish: BlockchainState
helper: Step
H: ReachableVia start finish helper actions
H0: donation_recorded user amount start
H1: forall act : Step, In act actions -> no_claims_from user actdonation_recorded user amount finishsnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevStdonation_recorded user amount (stepOnce prev)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevStdonation_recorded user amount prevStsnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevSt
H2: donation_recorded user amount prevStdonation_recorded user amount (stepOnce prev)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevStforall act : Step, In act prevList -> no_claims_from user actsnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevSt
H2: donation_recorded user amount prevStdonation_recorded user amount (stepOnce prev)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevSt
act: Step
H2: In act prevListno_claims_from user actsnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevSt
H2: donation_recorded user amount prevStdonation_recorded user amount (stepOnce prev)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevSt
act: Step
H2: In act prevListIn act (stepOnceAndWrap prev next_action :: prevList)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevSt
H2: donation_recorded user amount prevStdonation_recorded user amount (stepOnce prev)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H0: donation_recorded user amount start
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevSt
H2: donation_recorded user amount prevStdonation_recorded user amount (stepOnce prev)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
IHReachableVia: (forall act : Step, In act prevList -> no_claims_from user act) -> donation_recorded user amount prevSt
H2: donation_recorded user amount prevStdonation_recorded user amount (stepOnce prev)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: donation_recorded user amount prevStdonation_recorded user amount (stepOnce prev)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0get_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevListget_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevListno_claims_from user prevsnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevList
H0: no_claims_from user prevget_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevListIn prev (stepOnceAndWrap prev next_action :: prevList)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevList
H0: no_claims_from user prevget_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
x: list Step
H0: prev :: x = prevListIn prev (stepOnceAndWrap prev next_action :: prevList)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevList
H0: no_claims_from user prevget_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start: BlockchainState
prev: Step
x: list Step
H: ReachableVia start (Step_state prev) prev (prev :: x)
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prev :: x) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state (Step_state prev))) > 0In prev (stepOnceAndWrap prev next_action :: prev :: x)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevList
H0: no_claims_from user prevget_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start: BlockchainState
prev: Step
x: list Step
H: ReachableVia start (Step_state prev) prev (prev :: x)
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prev :: x) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state (Step_state prev))) > 0In prev (prev :: x)snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevList
H0: no_claims_from user prevget_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start: BlockchainState
prev: Step
x: list Step
H: ReachableVia start (Step_state prev) prev (prev :: x)
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prev :: x) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state (Step_state prev))) > 0prev = prevsnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevList
H0: no_claims_from user prevget_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prev: Step
prevList: list Step
H: ReachableVia start prevSt prev prevList
next_action: Action (stepOnce prev)
H1: forall act : Step, In act (stepOnceAndWrap prev next_action :: prevList) -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state prev
HReachableViaLinkStepToList: exists tl : list Step, prev :: tl = prevList
H0: no_claims_from user prevget_default 0 user (Crowdfunding_backers (contract_state (stepOnce prev))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H: ReachableVia start prevSt {| Step_state := Step_state0; Step_action := Step_action0 |} prevList
next_action: Action (stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |})
H1: forall act : Step, {| Step_state := stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |}; Step_action := next_action |} = act \/ In act prevList -> no_claims_from user act
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
HReachableViaLinkStepToList: exists tl : list Step, {| Step_state := Step_state0; Step_action := Step_action0 |} :: tl = prevList
H0: no_claims_from user {| Step_state := Step_state0; Step_action := Step_action0 |}get_default 0 user (Crowdfunding_backers (contract_state (stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |}))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H: ReachableVia start prevSt {| Step_state := Step_state0; Step_action := Step_action0 |} prevList
next_action: Action (stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |})
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
HReachableViaLinkStepToList: exists tl : list Step, {| Step_state := Step_state0; Step_action := Step_action0 |} :: tl = prevList
H0: no_claims_from user {| Step_state := Step_state0; Step_action := Step_action0 |}get_default 0 user (Crowdfunding_backers (contract_state (stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |}))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H: ReachableVia start prevSt {| Step_state := Step_state0; Step_action := Step_action0 |} prevList
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
HReachableViaLinkStepToList: exists tl : list Step, {| Step_state := Step_state0; Step_action := Step_action0 |} :: tl = prevList
H0: no_claims_from user {| Step_state := Step_state0; Step_action := Step_action0 |}get_default 0 user (Crowdfunding_backers (contract_state (stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |}))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
HReachableViaLinkStepToList: exists tl : list Step, {| Step_state := Step_state0; Step_action := Step_action0 |} :: tl = prevList
H0: no_claims_from user {| Step_state := Step_state0; Step_action := Step_action0 |}get_default 0 user (Crowdfunding_backers (contract_state (stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |}))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
H0: no_claims_from user {| Step_state := Step_state0; Step_action := Step_action0 |}get_default 0 user (Crowdfunding_backers (contract_state (stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |}))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
H0: match Step_action {| Step_state := Step_state0; Step_action := Step_action0 |} with | @call_Crowdfunding_claim _ _ _ _ _ _ => False | _ => True endget_default 0 user (Crowdfunding_backers (contract_state (stepOnce {| Step_state := Step_state0; Step_action := Step_action0 |}))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
H0: match Step_action {| Step_state := Step_state0; Step_action := Step_action0 |} with | @call_Crowdfunding_claim _ _ _ _ _ _ => False | _ => True endget_default 0 user (Crowdfunding_backers (contract_state (step (Step_state {| Step_state := Step_state0; Step_action := Step_action0 |}) (Step_action {| Step_state := Step_state0; Step_action := Step_action0 |})))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
H0: match Step_action {| Step_state := Step_state0; Step_action := Step_action0 |} with | @call_Crowdfunding_claim _ _ _ _ _ _ => False | _ => True endget_default 0 user (Crowdfunding_backers (contract_state (step Step_state0 Step_action0))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt, Step_state0: BlockchainState
Step_action0: Action Step_state0
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
HReachableViaLinkStateToStep: prevSt = Step_state0
H0: match Step_action {| Step_state := Step_state0; Step_action := Step_action0 |} with | @call_Crowdfunding_claim _ _ _ _ _ _ => False | _ => True endget_default 0 user (Crowdfunding_backers (contract_state (step Step_state0 Step_action0))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_donate_prf: runStateT (Crowdfunding_donate_opt (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers contract_state_after) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_getFunds_prf: runStateT (Crowdfunding_getFunds_opt (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers contract_state_after) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_claim_prf: runStateT (Crowdfunding_claim_opt (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Falseget_default 0 user (Crowdfunding_backers contract_state_after) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
sender, recipient: addr
amount0: wei
prf: sender <> contract_address /\ noOverflowOrUnderflowInTransfer sender recipient amount0 (balance prevSt) && address_accepts_funds_assumption None sender recipient amount0 = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
block_count, time_passing: int256
prf: validTimeChange block_count time_passing (block_number prevSt) (timestamp prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_donate_prf: runStateT (Crowdfunding_donate_opt (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers contract_state_after) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_donate_prf: runStateT (Crowdfunding_donate_opt (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers contract_state_after) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_donate_prf: runStateT ((v <- ret (negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)));; guard v);; (v <- ret ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0);; guard v);; gets Crowdfunding_backers;; spec2 <- ret (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption));; spec3 <- gets Crowdfunding_max_block;; (if Int256.ltu spec3 spec2 then ret tt;; v <- ret false;; guard v else spec4 <- gets (fun s : GetHighData => get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers s));; (if (spec4 =? 0)%Z then MonadState.modify (fun s : GetHighData => update_Crowdfunding_backers (set (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) (Crowdfunding_backers s)) s) else ret tt;; v <- ret false;; guard v))) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers contract_state_after) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
H19: false = trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = trueget_default 0 user (set (caller context) (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = false
H21: false = trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0match goal with H : false = true |- _ => inversion H end.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
H19: false = trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = trueget_default 0 user (set (caller context) (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: (user =? caller context) = trueget_default 0 user (set (caller context) (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: (user =? caller context) = falseget_default 0 user (set (caller context) (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: (user =? caller context) = trueget_default 0 user (set (caller context) (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: user = caller contextget_default 0 user (set (caller context) (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: user = caller contextget_default 0 user (set user (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: user = caller context(let (intval, _) := callvalue context in intval) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: user = caller contextFalsesnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 (caller context) (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = trueFalsesnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 (caller context) (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (caller context) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = trueFalsesnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 (caller context) (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: get_default 0 (caller context) (Crowdfunding_backers (contract_state prevSt)) = 0Falselia.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: 0 > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: get_default 0 (caller context) (Crowdfunding_backers (contract_state prevSt)) = 0Falsesnapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: (user =? caller context) = falseget_default 0 user (set (caller context) (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0rewrite get_default_so; assumption.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = true
Case: user <> caller contextget_default 0 user (set (caller context) (let (intval, _) := callvalue context in intval) (Crowdfunding_backers (contract_state prevSt))) > 0match goal with H : false = true |- _ => inversion H end.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: True
a: unit
H3: negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = true
a1: unit
H7: ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) >=? 0) = true
Heqb: Int256.ltu (Crowdfunding_max_block (contract_state prevSt)) (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) = false
Heqb0: (get_default 0 (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (Crowdfunding_backers (contract_state prevSt)) =? 0)%Z = false
H21: false = trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_getFunds_prf: runStateT (Crowdfunding_getFunds_opt (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers contract_state_after) > 0snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_getFunds_prf: runStateT (Crowdfunding_getFunds_opt (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers contract_state_after) > 0ds_inv; subst; simpl; try lia.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_getFunds_prf: runStateT ((v <- ret (negb (me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)));; guard v);; (v <- ret ((let (intval, _) := me_callvalue (make_machine_env contract_address prevSt context address_accepts_funds_assumption) in intval) =? 0)%Z;; guard v);; spec1 <- gets Crowdfunding_owner;; (if me_caller (make_machine_env contract_address prevSt context address_accepts_funds_assumption) =? spec1 then spec2 <- ret (me_number (make_machine_env contract_address prevSt context address_accepts_funds_assumption));; spec3 <- ret (let (intval, _) := me_balance (make_machine_env contract_address prevSt context address_accepts_funds_assumption) (me_address (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) in intval);; spec4 <- gets Crowdfunding_max_block;; (if Int256.ltu spec4 spec2 then spec5 <- gets Crowdfunding_goal;; (if spec5 <=? spec3 then MonadState.modify (update_Crowdfunding_funded true);; ret tt;; d <- MonadState.get;; (let (success, d') := me_transfer (...) spec1 (...) d in if success =? Int256.one then put d' else mzero) else ret tt) else ret tt) else ret tt)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers contract_state_after) > 0contradiction.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
context: CallContext
callvalue_prf: noOverflowOrUnderflowInTransfer (caller context) contract_address (callvalue context) (balance prevSt) = true
r: unit
contract_state_after: global_abstract_data_type
case_claim_prf: runStateT (Crowdfunding_claim_opt (make_machine_env contract_address prevSt context address_accepts_funds_assumption)) (contract_state prevSt) = Some (r, contract_state_after)
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Falseget_default 0 user (Crowdfunding_backers contract_state_after) > 0assumption.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
sender, recipient: addr
amount0: wei
prf: sender <> contract_address /\ noOverflowOrUnderflowInTransfer sender recipient amount0 (balance prevSt) && address_accepts_funds_assumption None sender recipient amount0 = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0assumption.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
block_count, time_passing: int256
prf: validTimeChange block_count time_passing (block_number prevSt) (timestamp prevSt) = true
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0assumption. Qed.snapshot_timestamp, snapshot_number: int256
snapshot_blockhash: int256 -> int256
snapshot_balances: addr -> wei
HmemOps, memModelOps: MemoryModelOps mem
contract_address: addr
address_accepts_funds: option ContractState -> addr -> addr -> wei -> bool
user: addr
amount: Z
start, prevSt: BlockchainState
prevList: list Step
H2: get_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
H0: Trueget_default 0 user (Crowdfunding_backers (contract_state prevSt)) > 0
If showing a part of this, show the very last Transparent and unfold of getFunds_opt. This shows something familiar that looks complex but is resolved via automation, because getFunds is what is called by the owner, so it has no bearing on the user donation record which is the focus of this lemma.
Also can show the first section, in particular after "Proof."
References
Thank you!
I would like to thank my supervisor Professor Steve Reeves at the University of Waikato and Vilhelm Sjöberg at CertiK for their valuable insights and input.
I would also like to thank Associate Professor Jing Sun and the University of Auckland for kindly hosting me during this research.
Inductive list (A : Type) : Type := | nil : list A | cons : A -> list A -> list A. Fixpoint contains (n:nat) (l:list nat) : bool := match l with | [] => false | h :: tl => (n =? h) || contains n tl end.
forall (n : nat) (list1 : list nat), contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = trueforall (n : nat) (list1 : list nat), contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = truen: natforall list1 : list nat, contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = truen: natcontains n [] = true -> forall list2 : list nat, contains n ([] ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = truecontains n (a :: list1) = true -> forall list2 : list nat, contains n ((a :: list1) ++ list2) = truen: natcontains n [] = true -> forall list2 : list nat, contains n ([] ++ list2) = truen: natfalse = true -> forall list2 : list nat, contains n list2 = truediscriminate.n: nat
H: false = true
list2: list natcontains n list2 = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = truecontains n (a :: list1) = true -> forall list2 : list nat, contains n ((a :: list1) ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: contains n (a :: list1) = true
list2: list natcontains n ((a :: list1) ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: (n =? a) || contains n list1 = true
list2: list nat(n =? a) || contains n (list1 ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: (n =? a) = true \/ contains n list1 = true
list2: list nat(n =? a) || contains n (list1 ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: (n =? a) = true
list2: list nat(n =? a) || contains n (list1 ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: contains n list1 = true
list2: list nat(n =? a) || contains n (list1 ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: (n =? a) = true
list2: list nat(n =? a) || contains n (list1 ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: (n =? a) = true
list2: list nat(n =? a) = true \/ contains n (list1 ++ list2) = trueassumption.n, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: (n =? a) = true
list2: list nat(n =? a) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: contains n list1 = true
list2: list nat(n =? a) || contains n (list1 ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: contains n list1 = true
list2: list nat(n =? a) = true \/ contains n (list1 ++ list2) = truen, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
H: contains n list1 = true
list2: list natcontains n (list1 ++ list2) = trueeassumption. Qed.n, a: nat
list1: list nat
IHlist1: contains n list1 = true -> forall list2 : list nat, contains n (list1 ++ list2) = true
list2: list nat
H: contains n (list1 ++ ?list2) = truecontains n (list1 ++ list2) = true
forall (n : nat) (l : list nat), contains n l = true <-> In n lforall (n : nat) (l : list nat), contains n l = true <-> In n lforall (n : nat) (l : list nat), contains n l = true <-> In n ln: nat
l: list natcontains n l = true -> In n ln: nat
l: list natIn n l -> contains n l = truen: nat
l: list natcontains n l = true -> In n ln: natcontains n [] = true -> In n []n, l': nat
l: list nat
IHl: contains n l = true -> In n lcontains n (l' :: l) = true -> In n (l' :: l)n: natcontains n [] = true -> In n []discriminate.n: natfalse = true -> Falsen, l': nat
l: list nat
IHl: contains n l = true -> In n lcontains n (l' :: l) = true -> In n (l' :: l)n, l': nat
l: list nat
IHl: contains n l = true -> In n l(n =? l') || contains n l = true -> l' = n \/ In n ln, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: (n =? l') || contains n l = truel' = n \/ In n ln, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: (n =? l') = true \/ contains n l = truel' = n \/ In n ln, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: (n =? l') = truel' = n \/ In n ln, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: contains n l = truel' = n \/ In n ln, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: (n =? l') = truel' = n \/ In n ln, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: (n =? l') = truel' = nauto.n, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: n = l'l' = nn, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: contains n l = truel' = n \/ In n ln, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: contains n l = trueIn n lassumption.n, l': nat
l: list nat
IHl: contains n l = true -> In n l
H: In n lIn n ln: nat
l: list natIn n l -> contains n l = truen: natIn n [] -> contains n [] = truen, l': nat
l: list nat
IHl: In n l -> contains n l = trueIn n (l' :: l) -> contains n (l' :: l) = truen: natIn n [] -> contains n [] = truecontradiction.n: natFalse -> false = truen, l': nat
l: list nat
IHl: In n l -> contains n l = trueIn n (l' :: l) -> contains n (l' :: l) = truen, l': nat
l: list nat
IHl: In n l -> contains n l = truel' = n \/ In n l -> (n =? l') || contains n l = truen, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: l' = n \/ In n l(n =? l') || contains n l = truen, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: l' = n(n =? l') || contains n l = truen, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: In n l(n =? l') || contains n l = truen, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: l' = n(n =? l') || contains n l = truen, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: l' = n(n =? l') = true \/ contains n l = truen, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: l' = n(n =? l') = trueapply Nat.eqb_refl.n: nat
l: list nat
IHl: In n l -> contains n l = true(n =? n) = truen, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: In n l(n =? l') || contains n l = truen, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: In n l(n =? l') = true \/ contains n l = trueauto. Qed.n, l': nat
l: list nat
IHl: In n l -> contains n l = true
H: In n lcontains n l = true
Inductive State := | initial | middle | extra | final . Inductive Transition (before : State) := | advance (prf : before <> final) | sidetrack (prf : before = initial).
Program Definition step (s : State) (t : Transition s) :=
match t with
| advance _ =>
match s with
| initial => middle
| middle => final
| extra => middle
| final => _
end
| sidetrack _ =>
match s with
| initial => extra
| _ => _
end
end.
forall (s : State) (t : Transition s) (wildcard' : s <> final), advance s wildcard' = t -> final = s -> States: State
t: Transition s
wildcard': s <> final
Heq_t: advance s wildcard' = t
Heq_s: final = sStates: State
t: Transition s
wildcard': s <> final
Heq_t: advance s wildcard' = t
Heq_s: final = sFalsecontradiction. Defined.wildcard': final <> finalFalseforall (s : State) (t : Transition s) (wildcard'0 : s = initial), sidetrack s wildcard'0 = t -> forall wildcard' : State, initial <> wildcard' -> wildcard' = s -> States: State
t: Transition s
wildcard'0: s = initial
Heq_t: sidetrack s wildcard'0 = t
wildcard': State
H: initial <> wildcard'
Heq_s: wildcard' = sStates: State
t: Transition s
wildcard'0: s = initial
Heq_t: sidetrack s wildcard'0 = t
wildcard': State
H: initial <> wildcard'
Heq_s: wildcard' = sFalsecontradiction. Defined.H: initial <> initialFalse
Local Obligation Tactic := try discriminate. (* Used for the above. *)
forall (t1 : Transition initial) (t2 : Transition (step initial t1)) (t3 : Transition (step (step initial t1) t2)), let s1 := step initial t1 in let s2 := step s1 t2 in step s2 t3 = finalforall (t1 : Transition initial) (t2 : Transition (step initial t1)) (t3 : Transition (step (step initial t1) t2)), let s1 := step initial t1 in let s2 := step s1 t2 in step s2 t3 = finalt1: Transition initial
t2: Transition (step initial t1)
t3: Transition (step (step initial t1) t2)
s1:= step initial t1: State
s2:= step s1 t2: Statestep s2 t3 = finalprf: initial <> final
t2: Transition (step initial (advance initial prf))
t3: Transition (step (step initial (advance initial prf)) t2)
s1:= step initial (advance initial prf): State
s2:= step s1 t2: Statestep s2 t3 = finalprf: initial = initial
t2: Transition (step initial (sidetrack initial prf))
t3: Transition (step (step initial (sidetrack initial prf)) t2)
s1:= step initial (sidetrack initial prf): State
s2:= step s1 t2: Statestep s2 t3 = finalprf: initial <> final
t2: Transition middle
t3: Transition (step middle t2)
s1:= middle: State
s2:= step s1 t2: Statestep s2 t3 = finalprf: initial = initial
t2: Transition (step initial (sidetrack initial prf))
t3: Transition (step (step initial (sidetrack initial prf)) t2)
s1:= step initial (sidetrack initial prf): State
s2:= step s1 t2: Statestep s2 t3 = finalprf: initial <> final
t2: Transition middle
t3: Transition (step middle t2)
s1:= middle: State
s2:= step s1 t2: Statestep s2 t3 = finalprf: initial <> final
prf0: middle <> final
t3: Transition (step middle (advance middle prf0))
s1:= middle: State
s2:= step s1 (advance middle prf0): Statestep s2 t3 = finalprf: initial <> final
prf0: middle = initial
t3: Transition (step middle (sidetrack middle prf0))
s1:= middle: State
s2:= step s1 (sidetrack middle prf0): Statestep s2 t3 = finalprf: initial <> final
prf0: middle <> final
t3: Transition final
s1:= middle: State
s2:= final: Statestep s2 t3 = finalprf: initial <> final
prf0: middle = initial
t3: Transition (step middle (sidetrack middle prf0))
s1:= middle: State
s2:= step s1 (sidetrack middle prf0): Statestep s2 t3 = finalprf: initial <> final
prf0: middle <> final
t3: Transition final
s1:= middle: State
s2:= final: Statestep s2 t3 = finalprf: initial <> final
prf0: middle <> final
prf1: final <> final
s1:= middle: State
s2:= final: Statestep s2 (advance final prf1) = finalprf: initial <> final
prf0: middle <> final
prf1: final = initial
s1:= middle: State
s2:= final: Statestep s2 (sidetrack final prf1) = finalcontradiction.prf: initial <> final
prf0: middle <> final
prf1: final <> final
s1:= middle: State
s2:= final: Statestep s2 (advance final prf1) = finaldiscriminate.prf: initial <> final
prf0: middle <> final
prf1: final = initial
s1:= middle: State
s2:= final: Statestep s2 (sidetrack final prf1) = finaldiscriminate.prf: initial <> final
prf0: middle = initial
t3: Transition (step middle (sidetrack middle prf0))
s1:= middle: State
s2:= step s1 (sidetrack middle prf0): Statestep s2 t3 = finalprf: initial = initial
t2: Transition (step initial (sidetrack initial prf))
t3: Transition (step (step initial (sidetrack initial prf)) t2)
s1:= step initial (sidetrack initial prf): State
s2:= step s1 t2: Statestep s2 t3 = finalprf: initial = initial
prf0: step initial (sidetrack initial prf) <> final
t3: Transition (step (step initial (sidetrack initial prf)) (advance (step initial (sidetrack initial prf)) prf0))
s1:= step initial (sidetrack initial prf): State
s2:= step s1 (advance (step initial (sidetrack initial prf)) prf0): Statestep s2 t3 = finalprf: initial = initial
prf0: step initial (sidetrack initial prf) = initial
t3: Transition (step (step initial (sidetrack initial prf)) (sidetrack (step initial (sidetrack initial prf)) prf0))
s1:= step initial (sidetrack initial prf): State
s2:= step s1 (sidetrack (step initial (sidetrack initial prf)) prf0): Statestep s2 t3 = finalprf: initial = initial
prf0: extra <> final
t3: Transition middle
s1:= extra: State
s2:= middle: Statestep s2 t3 = finalprf: initial = initial
prf0: step initial (sidetrack initial prf) = initial
t3: Transition (step (step initial (sidetrack initial prf)) (sidetrack (step initial (sidetrack initial prf)) prf0))
s1:= step initial (sidetrack initial prf): State
s2:= step s1 (sidetrack (step initial (sidetrack initial prf)) prf0): Statestep s2 t3 = finalprf: initial = initial
prf0: extra <> final
t3: Transition middle
s1:= extra: State
s2:= middle: Statestep s2 t3 = finalprf: initial = initial
prf0: extra <> final
prf1: middle <> final
s1:= extra: State
s2:= middle: Statestep s2 (advance middle prf1) = finalprf: initial = initial
prf0: extra <> final
prf1: middle = initial
s1:= extra: State
s2:= middle: Statestep s2 (sidetrack middle prf1) = finalprf: initial = initial
prf0: extra <> final
prf1: middle <> final
s1:= extra: State
s2:= middle: Statefinal = finalprf: initial = initial
prf0: extra <> final
prf1: middle = initial
s1:= extra: State
s2:= middle: Statestep s2 (sidetrack middle prf1) = finalreflexivity.prf: initial = initial
prf0: extra <> final
prf1: middle <> final
s1:= extra: State
s2:= middle: Statefinal = finaldiscriminate.prf: initial = initial
prf0: extra <> final
prf1: middle = initial
s1:= extra: State
s2:= middle: Statestep s2 (sidetrack middle prf1) = finaldiscriminate. Qed.prf: initial = initial
prf0: step initial (sidetrack initial prf) = initial
t3: Transition (step (step initial (sidetrack initial prf)) (sidetrack (step initial (sidetrack initial prf)) prf0))
s1:= step initial (sidetrack initial prf): State
s2:= step s1 (sidetrack (step initial (sidetrack initial prf)) prf0): Statestep s2 t3 = final