Best Python code snippet using molecule_python
test_puzzles.py
Source:test_puzzles.py  
1from typing import Iterable, List, Tuple2from unittest import TestCase3from blspy import AugSchemeMPL, BasicSchemeMPL, G1Element, G2Element4from hddcoin.types.blockchain_format.program import Program5from hddcoin.types.blockchain_format.sized_bytes import bytes326from hddcoin.types.coin_spend import CoinSpend7from hddcoin.types.spend_bundle import SpendBundle8from hddcoin.util.condition_tools import ConditionOpcode9from hddcoin.util.hash import std_hash10from hddcoin.wallet.puzzles import (11    p2_conditions,12    p2_delegated_conditions,13    p2_delegated_puzzle,14    p2_delegated_puzzle_or_hidden_puzzle,15    p2_m_of_n_delegate_direct,16    p2_puzzle_hash,17)18from tests.util.key_tool import KeyTool19from ..core.make_block_generator import int_to_public_key20from .coin_store import CoinStore, CoinTimestamp21T1 = CoinTimestamp(1, 10000000)22T2 = CoinTimestamp(5, 10003000)23MAX_BLOCK_COST_CLVM = int(1e18)24COST_PER_BYTE = int(12000)25def secret_exponent_for_index(index: int) -> int:26    blob = index.to_bytes(32, "big")27    hashed_blob = BasicSchemeMPL.key_gen(std_hash(b"foo" + blob))28    r = int.from_bytes(hashed_blob, "big")29    return r30def public_key_for_index(index: int, key_lookup: KeyTool) -> bytes:31    secret_exponent = secret_exponent_for_index(index)32    key_lookup.add_secret_exponents([secret_exponent])33    return bytes(int_to_public_key(secret_exponent))34def throwaway_puzzle_hash(index: int, key_lookup: KeyTool) -> bytes32:35    return p2_delegated_puzzle.puzzle_for_pk(public_key_for_index(index, key_lookup)).get_tree_hash()36def do_test_spend(37    puzzle_reveal: Program,38    solution: Program,39    payments: Iterable[Tuple[bytes32, int]],40    key_lookup: KeyTool,41    farm_time: CoinTimestamp = T1,42    spend_time: CoinTimestamp = T2,43) -> SpendBundle:44    """45    This method will farm a coin paid to the hash of `puzzle_reveal`, then try to spend it46    with `solution`, and verify that the created coins correspond to `payments`.47    The `key_lookup` is used to create a signed version of the `SpendBundle`, although at48    this time, signatures are not verified.49    """50    coin_db = CoinStore()51    puzzle_hash = puzzle_reveal.get_tree_hash()52    # farm it53    coin = coin_db.farm_coin(puzzle_hash, farm_time)54    # spend it55    coin_spend = CoinSpend(coin, puzzle_reveal, solution)56    spend_bundle = SpendBundle([coin_spend], G2Element())57    coin_db.update_coin_store_for_spend_bundle(spend_bundle, spend_time, MAX_BLOCK_COST_CLVM, COST_PER_BYTE)58    # ensure all outputs are there59    for puzzle_hash, amount in payments:60        for coin in coin_db.coins_for_puzzle_hash(puzzle_hash):61            if coin.amount == amount:62                break63        else:64            assert 065    # make sure we can actually sign the solution66    signatures = []67    for coin_spend in spend_bundle.coin_spends:68        signature = key_lookup.signature_for_solution(coin_spend, bytes([2] * 32))69        signatures.append(signature)70    return SpendBundle(spend_bundle.coin_spends, AugSchemeMPL.aggregate(signatures))71def default_payments_and_conditions(72    initial_index: int, key_lookup: KeyTool73) -> Tuple[List[Tuple[bytes32, int]], Program]:74    payments = [75        (throwaway_puzzle_hash(initial_index + 1, key_lookup), initial_index * 1000),76        (throwaway_puzzle_hash(initial_index + 2, key_lookup), (initial_index + 1) * 1000),77    ]78    conditions = Program.to([make_create_coin_condition(ph, amount) for ph, amount in payments])79    return payments, conditions80def make_create_coin_condition(puzzle_hash, amount):81    return Program.to([ConditionOpcode.CREATE_COIN, puzzle_hash, amount])82class TestPuzzles(TestCase):83    def test_p2_conditions(self):84        key_lookup = KeyTool()85        payments, conditions = default_payments_and_conditions(1, key_lookup)86        puzzle = p2_conditions.puzzle_for_conditions(conditions)87        solution = p2_conditions.solution_for_conditions(conditions)88        do_test_spend(puzzle, solution, payments, key_lookup)89    def test_p2_delegated_conditions(self):90        key_lookup = KeyTool()91        payments, conditions = default_payments_and_conditions(1, key_lookup)92        pk = public_key_for_index(1, key_lookup)93        puzzle = p2_delegated_conditions.puzzle_for_pk(pk)94        solution = p2_delegated_conditions.solution_for_conditions(conditions)95        do_test_spend(puzzle, solution, payments, key_lookup)96    def test_p2_delegated_puzzle_simple(self):97        key_lookup = KeyTool()98        payments, conditions = default_payments_and_conditions(1, key_lookup)99        pk = public_key_for_index(1, key_lookup)100        puzzle = p2_delegated_puzzle.puzzle_for_pk(pk)101        solution = p2_delegated_puzzle.solution_for_conditions(conditions)102        do_test_spend(puzzle, solution, payments, key_lookup)103    def test_p2_delegated_puzzle_graftroot(self):104        key_lookup = KeyTool()105        payments, conditions = default_payments_and_conditions(1, key_lookup)106        delegated_puzzle = p2_delegated_conditions.puzzle_for_pk(public_key_for_index(8, key_lookup))107        delegated_solution = p2_delegated_conditions.solution_for_conditions(conditions)108        puzzle_program = p2_delegated_puzzle.puzzle_for_pk(public_key_for_index(1, key_lookup))109        solution = p2_delegated_puzzle.solution_for_delegated_puzzle(delegated_puzzle, delegated_solution)110        do_test_spend(puzzle_program, solution, payments, key_lookup)111    def test_p2_puzzle_hash(self):112        key_lookup = KeyTool()113        payments, conditions = default_payments_and_conditions(1, key_lookup)114        inner_puzzle = p2_delegated_conditions.puzzle_for_pk(public_key_for_index(4, key_lookup))115        inner_solution = p2_delegated_conditions.solution_for_conditions(conditions)116        inner_puzzle_hash = inner_puzzle.get_tree_hash()117        puzzle_program = p2_puzzle_hash.puzzle_for_inner_puzzle_hash(inner_puzzle_hash)118        assert puzzle_program == p2_puzzle_hash.puzzle_for_inner_puzzle(inner_puzzle)119        solution = p2_puzzle_hash.solution_for_inner_puzzle_and_inner_solution(inner_puzzle, inner_solution)120        do_test_spend(puzzle_program, solution, payments, key_lookup)121    def test_p2_m_of_n_delegated_puzzle(self):122        key_lookup = KeyTool()123        payments, conditions = default_payments_and_conditions(1, key_lookup)124        pks = [public_key_for_index(_, key_lookup) for _ in range(1, 6)]125        M = 3126        delegated_puzzle = p2_conditions.puzzle_for_conditions(conditions)127        delegated_solution = []128        puzzle_program = p2_m_of_n_delegate_direct.puzzle_for_m_of_public_key_list(M, pks)129        selectors = [1, [], [], 1, 1]130        solution = p2_m_of_n_delegate_direct.solution_for_delegated_puzzle(131            M, selectors, delegated_puzzle, delegated_solution132        )133        do_test_spend(puzzle_program, solution, payments, key_lookup)134    def test_p2_delegated_puzzle_or_hidden_puzzle_with_hidden_puzzle(self):135        key_lookup = KeyTool()136        payments, conditions = default_payments_and_conditions(1, key_lookup)137        hidden_puzzle = p2_conditions.puzzle_for_conditions(conditions)138        hidden_public_key = public_key_for_index(10, key_lookup)139        puzzle = p2_delegated_puzzle_or_hidden_puzzle.puzzle_for_public_key_and_hidden_puzzle(140            hidden_public_key, hidden_puzzle141        )142        solution = p2_delegated_puzzle_or_hidden_puzzle.solution_for_hidden_puzzle(143            hidden_public_key, hidden_puzzle, Program.to(0)144        )145        do_test_spend(puzzle, solution, payments, key_lookup)146    def do_test_spend_p2_delegated_puzzle_or_hidden_puzzle_with_delegated_puzzle(self, hidden_pub_key_index):147        key_lookup = KeyTool()148        payments, conditions = default_payments_and_conditions(1, key_lookup)149        hidden_puzzle = p2_conditions.puzzle_for_conditions(conditions)150        hidden_public_key = public_key_for_index(hidden_pub_key_index, key_lookup)151        puzzle = p2_delegated_puzzle_or_hidden_puzzle.puzzle_for_public_key_and_hidden_puzzle(152            hidden_public_key, hidden_puzzle153        )154        payable_payments, payable_conditions = default_payments_and_conditions(5, key_lookup)155        delegated_puzzle = p2_conditions.puzzle_for_conditions(payable_conditions)156        delegated_solution = []157        synthetic_public_key = p2_delegated_puzzle_or_hidden_puzzle.calculate_synthetic_public_key(158            hidden_public_key, hidden_puzzle.get_tree_hash()159        )160        solution = p2_delegated_puzzle_or_hidden_puzzle.solution_for_delegated_puzzle(161            delegated_puzzle, delegated_solution162        )163        hidden_puzzle_hash = hidden_puzzle.get_tree_hash()164        synthetic_offset = p2_delegated_puzzle_or_hidden_puzzle.calculate_synthetic_offset(165            hidden_public_key, hidden_puzzle_hash166        )167        hidden_pub_key_point = G1Element.from_bytes(hidden_public_key)168        assert synthetic_public_key == int_to_public_key(synthetic_offset) + hidden_pub_key_point169        secret_exponent = key_lookup.get(hidden_public_key)170        assert int_to_public_key(secret_exponent) == hidden_pub_key_point171        synthetic_secret_exponent = secret_exponent + synthetic_offset172        key_lookup.add_secret_exponents([synthetic_secret_exponent])173        do_test_spend(puzzle, solution, payable_payments, key_lookup)174    def test_p2_delegated_puzzle_or_hidden_puzzle_with_delegated_puzzle(self):175        for hidden_pub_key_index in range(1, 10):...public_delegated_prefixes.py
Source:public_delegated_prefixes.py  
1# -*- coding: utf-8 -*- #2# Copyright 2019 Google LLC. All Rights Reserved.3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8#    http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15"""Public delegated prefixes api client."""16from __future__ import absolute_import17from __future__ import division18from __future__ import unicode_literals19from googlecloudsdk.api_lib.compute.operations import poller20from googlecloudsdk.api_lib.util import waiter21from googlecloudsdk.core.exceptions import Error22class PublicDelegatedPrefixPatchError(Error):23  """Raised when an invalid update to PublicDelegatedPrefix is attempted."""24class PublicDelegatedPrefixesClient(object):25  """Client for public delegated prefixes service in the GCE API."""26  def __init__(self, client, messages, resources):27    self.client = client28    self.messages = messages29    self.resources = resources30    self._global_service = self.client.apitools_client.globalPublicDelegatedPrefixes31    self._regional_service = self.client.apitools_client.publicDelegatedPrefixes32  def Create(self, pdp_ref, parent_prefix, ip_cidr_range, description,33             enable_live_migration):34    """Creates a public delegated prefix."""35    is_regional = hasattr(pdp_ref, 'region')36    parent_prefix_ref = self.resources.Parse(37        parent_prefix, {'project': pdp_ref.project},38        collection='compute.publicAdvertisedPrefixes')39    parent_prefix_uri = parent_prefix_ref.SelfLink()40    public_delegated_prefix = self.messages.PublicDelegatedPrefix(41        name=pdp_ref.Name(),42        parentPrefix=parent_prefix_uri,43        ipCidrRange=ip_cidr_range,44        description=description,45        isLiveMigration=enable_live_migration)46    if is_regional:47      request = self.messages.ComputePublicDelegatedPrefixesInsertRequest(48          publicDelegatedPrefix=public_delegated_prefix,49          project=pdp_ref.project,50          region=pdp_ref.region)51      return self.client.MakeRequests([(self._regional_service, 'Insert',52                                        request)])[0]53    else:54      request = self.messages.ComputeGlobalPublicDelegatedPrefixesInsertRequest(55          publicDelegatedPrefix=public_delegated_prefix,56          project=pdp_ref.project)57      return self.client.MakeRequests([(self._global_service, 'Insert', request)58                                      ])[0]59  def Delete(self, pdp_ref):60    """Deletes a public delegated prefix."""61    is_regional = hasattr(pdp_ref, 'region')62    if is_regional:63      request = self.messages.ComputePublicDelegatedPrefixesDeleteRequest(64          publicDelegatedPrefix=pdp_ref.Name(),65          project=pdp_ref.project,66          region=pdp_ref.region)67      return self.client.MakeRequests([(self._regional_service, 'Delete',68                                        request)])69    else:70      request = self.messages.ComputeGlobalPublicDelegatedPrefixesDeleteRequest(71          publicDelegatedPrefix=pdp_ref.Name(), project=pdp_ref.project)72      return self.client.MakeRequests([(self._global_service, 'Delete', request)73                                      ])74  def Get(self, pdp_ref):75    """Gets a public delegated prefix."""76    is_regional = hasattr(pdp_ref, 'region')77    if is_regional:78      request = self.messages.ComputePublicDelegatedPrefixesGetRequest(79          publicDelegatedPrefix=pdp_ref.Name(),80          project=pdp_ref.project,81          region=pdp_ref.region)82      return self.client.MakeRequests([(self._regional_service, 'Get', request)83                                      ])[0]84    else:85      request = self.messages.ComputeGlobalPublicDelegatedPrefixesGetRequest(86          publicDelegatedPrefix=pdp_ref.Name(), project=pdp_ref.project)87      return self.client.MakeRequests([(self._global_service, 'Get', request)88                                      ])[0]89  def _Patch(self, pdp_ref, resource):90    """Patches a public delegated prefix resource.91    Args:92      pdp_ref: resource reference.93      resource: PublicDelegatedPrefix resource.94    Returns:95      Operation result from the poller.96    """97    # Drop all fields except fingerprint and modifiable ones.98    resource = self.messages.PublicDelegatedPrefix(99        fingerprint=resource.fingerprint,100        publicDelegatedSubPrefixs=resource.publicDelegatedSubPrefixs)101    include_fields = []102    if not resource.publicDelegatedSubPrefixs:103      include_fields.append('publicDelegatedSubPrefixs')104    is_regional = hasattr(pdp_ref, 'region')105    if is_regional:106      request = self.messages.ComputePublicDelegatedPrefixesPatchRequest(107          publicDelegatedPrefix=pdp_ref.Name(),108          publicDelegatedPrefixResource=resource,109          project=pdp_ref.project,110          region=pdp_ref.region)111      with self.client.apitools_client.IncludeFields(include_fields):112        operation = self._regional_service.Patch(request)113      operation_ref = self.resources.Parse(114          operation.selfLink, collection='compute.regionOperations')115      operation_poller = poller.Poller(self._regional_service)116    else:117      request = self.messages.ComputeGlobalPublicDelegatedPrefixesPatchRequest(118          publicDelegatedPrefix=pdp_ref.Name(),119          publicDelegatedPrefixResource=resource,120          project=pdp_ref.project)121      with self.client.apitools_client.IncludeFields(include_fields):122        operation = self._global_service.Patch(request)123      operation_ref = self.resources.Parse(124          operation.selfLink, collection='compute.globalOperations')125      operation_poller = poller.Poller(self._global_service)126    return waiter.WaitFor(127        operation_poller, operation_ref,128        'Updating public delegated prefix [{}].'.format(pdp_ref.Name()))129  def AddSubPrefix(self, pdp_ref, name, ip_cidr_range, description,130                   delegatee_project, is_addresses):131    """Adds a delegated sub prefix to public delegated prefix using PATCH.132    Args:133      pdp_ref: resource reference.134      name: sub prefix name.135      ip_cidr_range: sub prefix IP address range.136      description: sub prefix description.137      delegatee_project: sub prefix target project.138      is_addresses: sub prefix isAddress parameter.139    Returns:140      Operation result from the poller.141    Raises:142      PublicDelegatedPrefixPatchError:143        when delegated prefix already has a sub prefix with specified name.144    """145    resource = self.Get(pdp_ref)146    for sub_prefix in resource.publicDelegatedSubPrefixs:147      if sub_prefix.name == name:148        raise PublicDelegatedPrefixPatchError(149            'Delegated sub prefix [{}] already exists in public delegated '150            'prefix [{}]'.format(name, pdp_ref.Name()))151    resource.publicDelegatedSubPrefixs.append(152        self.messages.PublicDelegatedPrefixPublicDelegatedSubPrefix(153            name=name,154            description=description,155            ipCidrRange=ip_cidr_range,156            delegateeProject=delegatee_project,157            isAddress=is_addresses))158    return self._Patch(pdp_ref, resource)159  def RemoveSubPrefix(self, pdp_ref, name):160    """Removes a delegated sub prefix from public delegated prefix using PATCH.161    Args:162      pdp_ref: resource reference.163      name: name of sub prefix to remove.164    Returns:165      Operation result from the poller.166    Raises:167      PublicDelegatedPrefixPatchError:168        when delegated prefix does not have a sub prefix with specified name.169    """170    resource = self.Get(pdp_ref)171    index_to_remove = None172    for i, sub_prefix in enumerate(resource.publicDelegatedSubPrefixs):173      if sub_prefix.name == name:174        index_to_remove = i175    if index_to_remove is None:176      raise PublicDelegatedPrefixPatchError(177          'Delegated sub prefix [{}] does not exist in public delegated '178          'prefix [{}]'.format(name, pdp_ref.Name()))179    resource.publicDelegatedSubPrefixs.pop(index_to_remove)180    return self._Patch(pdp_ref, resource)181  def Announce(self, pdp_ref):182    """Announce a public delegated prefix."""183    request = self.messages.ComputePublicDelegatedPrefixesAnnounceRequest(184        publicDelegatedPrefix=pdp_ref.Name(),185        project=pdp_ref.project,186        region=pdp_ref.region)187    return self.client.MakeRequests([(self._regional_service, 'Announce',188                                      request)])189  def Withdraw(self, pdp_ref):190    """Withdraw a public delegated prefix."""191    request = self.messages.ComputePublicDelegatedPrefixesWithdrawRequest(192        publicDelegatedPrefix=pdp_ref.Name(),193        project=pdp_ref.project,194        region=pdp_ref.region)195    return self.client.MakeRequests([(self._regional_service, 'Withdraw',...VariableDebtToken.spec
Source:VariableDebtToken.spec  
1using LendingPoolHarnessForVariableDebtToken as POOL2/**3Checks that each possible opertaion changes the balance of at most one user.4*/5rule balanceOfChange(address a, address b, method f)6{7	env e;8	require a != b;9	uint256 balanceABefore = sinvoke balanceOf(e, a);10	uint256 balanceBBefore = sinvoke balanceOf(e, b);11	 12	calldataarg arg;13	sinvoke f(e, arg); 14	uint256 balanceAAfter = sinvoke balanceOf(e, a);15	uint256 balanceBAfter = sinvoke balanceOf(e, b);16	17	assert (balanceABefore == balanceAAfter || balanceBBefore == balanceBAfter);18}19/**20Checks that the change to total supply is coherent with the change to the balance due to an operation21(which is neither a burn nor a mint).22*/23rule integirtyBalanceOfTotalSupply(address a, method f)24{25	env e;26	27	uint256 balanceABefore = balanceOf(e, a);28	uint256 totalSupplyBefore = totalSupply(e);29	 30	calldataarg arg;31	sinvoke f(e, arg); 32	require (f.selector != burn(address, uint256, uint256).selector  &&33		f.selector != mint(address, address, uint256, uint256).selector);34	uint256 balanceAAfter = balanceOf(e, a);35	uint256 totalSupplyAfter = totalSupply(e);36	assert  (balanceAAfter != balanceABefore  => ( balanceAAfter - balanceABefore  == totalSupplyAfter - totalSupplyBefore));37}38/**39Checks that the change to total supply is coherent with the change to the balance due to a burn operation.40*/41rule integirtyBalanceOfTotalSupplyOnBurn(address a)42{43	env e;44	45	uint256 balanceABefore = balanceOf(e, a);46	uint256 totalSupplyBefore = totalSupply(e);47	 48	uint256 x;49	address asset;50	uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);51	sinvoke burn(e, a, x, index); 52	uint256 balanceAAfter = balanceOf(e, a);53	uint256 totalSupplyAfter = totalSupply(e);54	assert (balanceAAfter != balanceABefore  => (balanceAAfter - balanceABefore  == totalSupplyAfter - totalSupplyBefore));55}56/**57Checks that the change to total supply is coherent with the change to the balance due to a mint operation.58*/59rule integirtyBalanceOfTotalSupplyOnMint(address u, address delegatedUser)60{61	env e;62	63	uint256 balanceUBefore = balanceOf(e, u);64	uint256 totalSupplyBefore = totalSupply(e);65	 66	uint256 x;67	address asset;68	uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);69	sinvoke mint(e, delegatedUser, u, x, index); 70	uint256 balanceUAfter = balanceOf(e, u);71	uint256 totalSupplyAfter = totalSupply(e);72	assert (balanceUAfter != balanceUBefore  => (balanceUAfter - balanceUBefore  == totalSupplyAfter - totalSupplyBefore));73}74/**75Minting an amount of x tokens for user u increases her balance by x, up to rounding errors. 76{ b = balanceOf(u,t) } 77mint(delegatedUser, u, x, index) 78{ balanceOf(u,t) = b + x }.79Also, if the minting is done by a user delegatedUser different than u, the balance of delegatedUser80remains unchanged.81*/82rule integrityMint(address u, address delegatedUser, uint256 x) {83	env e;84	address asset;85	uint256 index = POOL.getReserveNormalizedVariableDebt(e,asset);86	uint256 balanceUBefore = balanceOf(e, u);87	uint256 balanceDelegatedUBefore = balanceOf(e, delegatedUser);88	sinvoke mint(e, delegatedUser, u, x, index);89	90	uint256 balanceUAfter = balanceOf(e, u);91	uint256 balanceDelegatedUAfter = balanceOf(e, delegatedUser);92	93	assert balanceUAfter == balanceUBefore + x && (u != delegatedUser => (balanceDelegatedUAfter == balanceDelegatedUBefore));94}95/**96Mint is additive, namely it can performed either all at once or gradually:97mint(delegatedUser, u, x, index); mint(delegatedUser, u, y, index) ~ mint(delegatedUser, u, x+y, index) at the same timestamp.98*/99rule additiveMint(address a, address delegatedUser, uint256 x, uint256 y) {100	env e;101	address asset;102	uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);103	storage initialStorage = lastStorage;104	sinvoke mint(e, delegatedUser, a, x, index);105	sinvoke mint(e, delegatedUser, a, y, index);106	uint256 balanceScenario1 = balanceOf(e, a);107	uint256 t = x + y;108	sinvoke mint(e, delegatedUser, a, t ,index) at initialStorage;109	uint256 balanceScenario2 = balanceOf(e, a);110	assert balanceScenario1 == balanceScenario2, "mint is not additive";111}112/** 113Burning an amount of x tokens for user u decreases her balance by x, up to rounding errors. 114{ bu = balanceOf(u) } 115	burn(u, x)116{ balanceOf(u) = bu - x }.117*/118rule integrityBurn(address a, uint256 x) {119	env e;120	address asset;121	uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);122	uint256 balancebefore = balanceOf(e, a);123	sinvoke burn(e, a, x, index);124	125	uint256 balanceAfter = balanceOf(e, a);126	assert balanceAfter == balancebefore - x;127}128/**129Minting is additive, i.e., it can be performed either all at once or in steps:130burn(u, x); burn(u, y) ~ burn(u, x+y) at the same timestamp.131*/132rule additiveBurn(address a, uint256 x,  uint256 y) {133	env e;134	address asset;135	uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);136	storage initialStorage = lastStorage;137	sinvoke burn(e, a, x, index);138	sinvoke burn(e, a, y, index);139	uint256 balanceScenario1 = balanceOf(e, a);140	uint256 t = x + y;141	sinvoke burn(e, a, t ,index) at initialStorage;142	uint256 balanceScenario2 = balanceOf(e, a);143	assert balanceScenario1 == balanceScenario2, "burn is not additive";144}145/**146Minting and burning are inverse operations:147{ bu = balanceOf(u) } 148mint(u,x); burn(u, u, x) 149{ balanceOf(u) = bu }.150*/151rule inverseMintBurn(address a, uint256 x) {152	env e;153	address asset;154	address delegatedUser;155	uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);156	uint256 balancebefore = balanceOf(e, a);157	sinvoke mint(e, delegatedUser, a, x, index);158	sinvoke burn(e, a, x, index);159	uint256 balanceAfter = balanceOf(e, a);160	assert balancebefore == balanceAfter, "burn is not the inverse of mint";...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
