CVE-2024-39696 (published 2024-07-05T19:15Z)

Evmos is a decentralized Ethereum Virtual Machine chain on the Cosmos Network. Prior to version 19.0.0, a user can create a vesting account with a 3rd party account (EOA or contract) as funder. Then, this user can create an authorization for the contract.CallerAddress, this is the authorization checked in the code. But the funds are taken from the funder address provided in the message. Consequently, the user can fund a vesting account with a 3rd party account without its permission. The funder address can be any address, so this vulnerability can be used to drain all the accounts in the chain. The issue has been patched in version 19.0.0.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/evmos/evmos
commit_details: repo_url: https://github.com/evmos/evmos
author: Tom
author_date: 2024-07-05 11:45:14-03:00
msg: Merge pull request from GHSA-q6hg-6m9x-5g9c

* fix(precompile): add funder and dest check to update balance

* add more test cases

* restrict funder to be origin or contract caller

* restrict dest address when calling from sc

* add test case with funds transfer within precompile call

* remove print

* add check for dirty addresses

* add UpdateDirties func

* update dirties helper func

* Update precompiles/vesting/utils_test.go

Co-authored-by: stepit <48993133+0xstepit@users.noreply.github.com>
Signed-off-by: Tom <54514587+GAtom22@users.noreply.github.com>

* update comment description

* changes based on review comments

* refactor updateDirties

* add test cases for updating funder balance before and after precompile call

* add revert state test

* update tx logic

* update integration tests

* refactor auth logic

* update tests

* add comt

* fix: add funder and vest acc to dirties

* add test cases for latest changes

* address review comments

* address review comments

* address review comments

* fix FlashLoan contract compilation

* update logic

* use pointer in precompile txs

* remove unnecessary comment

---------

Signed-off-by: Tom <54514587+GAtom22@users.noreply.github.com>
Co-authored-by: stepit <48993133+0xstepit@users.noreply.github.com>
repository: repo_url: https://github.com/evmos/evmos
repo_name: evmos/evmos
description: Evmos is the first decentralized EVM chain on the Cosmos Network.  It's implementing the first EVM stack focused on native, cross-chain applications. Evmos is the flagship implementation of Ethermint, an EVM library built for the Cosmos Network by the Evmos Core Developement Team.
repo_language: Go
owner: evmos
file_changes: filename: Counter.json
change_type: ModificationType.ADD
diff: @@ -0,0 +1,64 @@
+{
+  "_format": "hh-sol-artifact-1",
+  "contractName": "Counter",
+  "sourceName": "solidity/precompiles/testutil/contracts/Counter.sol",
+  "abi": [
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "counter",
+          "type": "uint256"
+        }
+      ],
+      "name": "Added",
+      "type": "event"
+    },
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "counter",
+          "type": "uint256"
+        }
+      ],
+      "name": "Changed",
+      "type": "event"
+    },
+    {
+      "inputs": [],
+      "name": "add",
+      "outputs": [],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "getCounter",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "subtract",
+      "outputs": [],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    }
+  ],
+  "bytecode": "0x60806040526000805534801561001457600080fd5b50610397806100246000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80634f2be91f146100465780636deebae3146100505780638ada066e1461005a575b600080fd5b61004e610078565b005b610058610103565b005b6100626101d2565b60405161006f91906101f4565b60405180910390f35b60008081548092919061008a9061023e565b91905055507f64a55044d1f2eddebe1b90e8e2853e8e96931cefadbfa0b2ceb34bee360619416000546040516100c091906101f4565b60405180910390a17f938d2ee5be9cfb0f7270ee2eff90507e94b37625d9d2b3a61c97d30a4560b8296000546040516100f991906101f4565b60405180910390a1565b60008054116040518060400160405280600f81526020017f434f554e5445525f544f4f5f4c4f5700000000000000000000000000000000008152509061017f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101769190610316565b60405180910390fd5b5060008081548092919061019290610338565b91905055507f938d2ee5be9cfb0f7270ee2eff90507e94b37625d9d2b3a61c97d30a4560b8296000546040516101c891906101f4565b60405180910390a1565b60008054905090565b6000819050919050565b6101ee816101db565b82525050565b600060208201905061020960008301846101e5565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610249826101db565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361027b5761027a61020f565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b60005b838110156102c05780820151818401526020810190506102a5565b60008484015250505050565b6000601f19601f8301169050919050565b60006102e882610286565b6102f28185610291565b93506103028185602086016102a2565b61030b816102cc565b840191505092915050565b6000602082019050818103600083015261033081846102dd565b905092915050565b6000610343826101db565b9150600082036103565761035561020f565b5b60018203905091905056fea26469706673582212202870b2d78304eb0ec6b95f72bacf96e449481ecaa4d58a3ce786c1cba532075d64736f6c63430008130033",
+  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80634f2be91f146100465780636deebae3146100505780638ada066e1461005a575b600080fd5b61004e610078565b005b610058610103565b005b6100626101d2565b60405161006f91906101f4565b60405180910390f35b60008081548092919061008a9061023e565b91905055507f64a55044d1f2eddebe1b90e8e2853e8e96931cefadbfa0b2ceb34bee360619416000546040516100c091906101f4565b60405180910390a17f938d2ee5be9cfb0f7270ee2eff90507e94b37625d9d2b3a61c97d30a4560b8296000546040516100f991906101f4565b60405180910390a1565b60008054116040518060400160405280600f81526020017f434f554e5445525f544f4f5f4c4f5700000000000000000000000000000000008152509061017f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101769190610316565b60405180910390fd5b5060008081548092919061019290610338565b91905055507f938d2ee5be9cfb0f7270ee2eff90507e94b37625d9d2b3a61c97d30a4560b8296000546040516101c891906101f4565b60405180910390a1565b60008054905090565b6000819050919050565b6101ee816101db565b82525050565b600060208201905061020960008301846101e5565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610249826101db565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361027b5761027a61020f565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b60005b838110156102c05780820151818401526020810190506102a5565b60008484015250505050565b6000601f19601f8301169050919050565b60006102e882610286565b6102f28185610291565b93506103028185602086016102a2565b61030b816102cc565b840191505092915050565b6000602082019050818103600083015261033081846102dd565b905092915050565b6000610343826101db565b9150600082036103565761035561020f565b5b60018203905091905056fea26469706673582212202870b2d78304eb0ec6b95f72bacf96e449481ecaa4d58a3ce786c1cba532075d64736f6c63430008130033",
+  "linkReferences": {},
+  "deployedLinkReferences": {}
+}

programming_language: Jupyter Notebook
filename: Counter.sol
change_type: ModificationType.ADD
diff: @@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-3.0
+
+pragma solidity >=0.7.0 <0.9.0;
+
+contract Counter {
+  uint256 counter = 0;
+  string internal constant ERROR_TOO_LOW = "COUNTER_TOO_LOW";
+  event Changed(uint256 counter);
+  event Added(uint256 counter);
+
+  function add() public {
+    counter++;
+    emit Added(counter);
+    emit Changed(counter);
+  }
+
+  function subtract() public {
+    require(counter > 0, ERROR_TOO_LOW);
+    counter--;
+    emit Changed(counter);
+  }
+
+  function getCounter() public view returns (uint256) {
+    return counter;
+  }
+}

programming_language: Java
filename: DistributionCaller.json
change_type: ModificationType.MODIFY
diff: @@ -914,8 +914,8 @@
       "type": "function"
     }
   ],
-  "bytecode": "0x608060405234801561001057600080fd5b5061477b806100206000396000f3fe60806040526004361061019c5760003560e01c80637c9db0bb116100ec578063b6a216ae1161008a578063d0e30db011610064578063d0e30db0146106a7578063d3f831be146106b1578063e0421e39146106ee578063e236c7a61461072b5761019c565b8063b6a216ae146105f0578063c7804bb51461062d578063cb85aa0a1461066a5761019c565b806398194593116100c657806398194593146104fc578063ad5c4cdd14610539578063adb2378514610576578063b2d17883146105b35761019c565b80637c9db0bb1461044457806388b2d58114610481578063963516e4146104bf5761019c565b806346e16d34116101595780636cc9ac8a116101335780636cc9ac8a146103785780636f669da4146103a157806378a5dfd1146103de578063796b96d21461041b5761019c565b806346e16d34146102d3578063613d4de81461031057806361bc221a1461034d5761019c565b80630183e4b4146101a157806301b68000146101ca5780630c05e9e4146102075780631b05020714610244578063296c60aa1461026d5780632d0ee16a14610296575b600080fd5b3480156101ad57600080fd5b506101c860048036038101906101c391906123de565b610769565b005b3480156101d657600080fd5b506101f160048036038101906101ec9190612483565b610a96565b6040516101fe9190612540565b60405180910390f35b34801561021357600080fd5b5061022e60048036038101906102299190612697565b610bde565b60405161023b91906128da565b60405180910390f35b34801561025057600080fd5b5061026b600480360381019061026691906128fc565b610c6e565b005b34801561027957600080fd5b50610294600480360381019061028f919061297f565b610df4565b005b3480156102a257600080fd5b506102bd60048036038101906102b89190612697565b610f35565b6040516102ca9190612ada565b60405180910390f35b3480156102df57600080fd5b506102fa60048036038101906102f5919061297f565b610fc3565b6040516103079190612b0b565b60405180910390f35b34801561031c57600080fd5b5061033760048036038101906103329190612b26565b61104d565b6040516103449190612ada565b60405180910390f35b34801561035957600080fd5b5061036261133e565b60405161036f9190612bc5565b60405180910390f35b34801561038457600080fd5b5061039f600480360381019061039a9190612c0c565b61134f565b005b3480156103ad57600080fd5b506103c860048036038101906103c39190612c73565b6115de565b6040516103d59190612b0b565b60405180910390f35b3480156103ea57600080fd5b506104056004803603810190610400919061297f565b611668565b6040516104129190612d39565b60405180910390f35b34801561042757600080fd5b50610442600480360381019061043d919061297f565b6116f5565b005b34801561045057600080fd5b5061046b60048036038101906104669190612697565b611836565b6040516104789190612d39565b60405180910390f35b34801561048d57600080fd5b506104a860048036038101906104a39190612dbf565b6118c0565b6040516104b6929190613001565b60405180910390f35b3480156104cb57600080fd5b506104e660048036038101906104e19190612697565b61195e565b6040516104f39190612b0b565b60405180910390f35b34801561050857600080fd5b50610523600480360381019061051e919061297f565b6119e7565b6040516105309190612ada565b60405180910390f35b34801561054557600080fd5b50610560600480360381019061055b919061297f565b611a76565b60405161056d9190612ada565b60405180910390f35b34801561058257600080fd5b5061059d60048036038101906105989190613038565b611b02565b6040516105aa9190612ada565b60405180910390f35b3480156105bf57600080fd5b506105da60048036038101906105d591906130bb565b611d8d565b6040516105e79190612ada565b60405180910390f35b3480156105fc57600080fd5b5061061760048036038101906106129190612483565b611ee2565b6040516106249190613208565b60405180910390f35b34801561063957600080fd5b50610654600480360381019061064f919061322a565b611f6c565b6040516106619190612b0b565b60405180910390f35b34801561067657600080fd5b50610691600480360381019061068c9190612483565b612084565b60405161069e91906132b4565b60405180910390f35b6106af61210e565b005b3480156106bd57600080fd5b506106d860048036038101906106d39190612697565b612110565b6040516106e59190612d39565b60405180910390f35b3480156106fa57600080fd5b5061071560048036038101906107109190612697565b61219a565b6040516107229190612ada565b60405180910390f35b34801561073757600080fd5b50610752600480360381019061074d9190612483565b612226565b6040516107609291906133dc565b60405180910390f35b811561089a5760008081819054906101000a900460070b8092919061078d90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146108995760008473ffffffffffffffffffffffffffffffffffffffff16600f604051610811906134a3565b60006040518083038185875af1925050503d806000811461084e576040519150601f19603f3d011682016040523d82523d6000602084013e610853565b606091505b5050905080610897576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088e9061352a565b60405180910390fd5b505b5b600061080173ffffffffffffffffffffffffffffffffffffffff16632efe8a5f86866040518363ffffffff1660e01b81526004016108d99291906135b8565b6020604051808303816000875af11580156108f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091c91906135f6565b90508061095e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061366f565b60405180910390fd5b8115610a8f5760008081819054906101000a900460070b8092919061098290613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610a8e5760008573ffffffffffffffffffffffffffffffffffffffff16600f604051610a06906134a3565b60006040518083038185875af1925050503d8060008114610a43576040519150601f19603f3d011682016040523d82523d6000602084013e610a48565b606091505b5050905080610a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a839061352a565b60405180910390fd5b505b5b5050505050565b606060008061080173ffffffffffffffffffffffffffffffffffffffff1684604051602401610ac5919061369e565b6040516020818303038152906040527f5431f450000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610b4f91906136ea565b600060405180830381855afa9150503d8060008114610b8a576040519150601f19603f3d011682016040523d82523d6000602084013e610b8f565b606091505b509150915081610bd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcb9061374d565b60405180910390fd5b8092505050919050565b610be66122b3565b61080173ffffffffffffffffffffffffffffffffffffffff166354212a89836040518263ffffffff1660e01b8152600401610c2191906132b4565b600060405180830381865afa158015610c3e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610c679190613a46565b9050919050565b3073ffffffffffffffffffffffffffffffffffffffff1663ad5c4cdd85846040518363ffffffff1660e01b8152600401610ca9929190613a8f565b6000604051808303816000875af1925050508015610cea57506040513d6000823e3d601f19601f82011682018060405250810190610ce79190613c0c565b60015b15610cf157505b8015610dee5760008081819054906101000a900460070b80929190610d1590613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008373ffffffffffffffffffffffffffffffffffffffff16600f604051610d66906134a3565b60006040518083038185875af1925050503d8060008114610da3576040519150601f19603f3d011682016040523d82523d6000602084013e610da8565b606091505b5050905080610dec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de39061352a565b60405180910390fd5b505b50505050565b600061080173ffffffffffffffffffffffffffffffffffffffff168383604051602401610e22929190613c55565b6040516020818303038152906040527f5a9d9a96000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610eac91906136ea565b600060405180830381855af49150503d8060008114610ee7576040519150601f19603f3d011682016040523d82523d6000602084013e610eec565b606091505b5050905080610f30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2790613cf7565b60405180910390fd5b505050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6130846040518363ffffffff1660e01b8152600401610f74929190613c55565b6000604051808303816000875af1158015610f93573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610fbc9190613c0c565b9050919050565b600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9684846040518363ffffffff1660e01b8152600401611002929190613c55565b6020604051808303816000875af1158015611021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104591906135f6565b905092915050565b606082156111805760008081819054906101000a900460070b8092919061107390613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461117f5760008473ffffffffffffffffffffffffffffffffffffffff16600f6040516110f7906134a3565b60006040518083038185875af1925050503d8060008114611134576040519150601f19603f3d011682016040523d82523d6000602084013e611139565b606091505b505090508061117d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111749061352a565b60405180910390fd5b505b5b61080173ffffffffffffffffffffffffffffffffffffffff16633ce4e3be866040518263ffffffff1660e01b81526004016111bb91906132b4565b6000604051808303816000875af11580156111da573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112039190613c0c565b905081156113365760008081819054906101000a900460070b8092919061122990613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146113355760008473ffffffffffffffffffffffffffffffffffffffff16600f6040516112ad906134a3565b60006040518083038185875af1925050503d80600081146112ea576040519150601f19603f3d011682016040523d82523d6000602084013e6112ef565b606091505b5050905080611333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132a9061352a565b60405180910390fd5b505b5b949350505050565b60008054906101000a900460070b81565b811561144c5760008081819054906101000a900460070b8092919061137390613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008473ffffffffffffffffffffffffffffffffffffffff16600f6040516113c4906134a3565b60006040518083038185875af1925050503d8060008114611401576040519150601f19603f3d011682016040523d82523d6000602084013e611406565b606091505b505090508061144a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114419061352a565b60405180910390fd5b505b600061080173ffffffffffffffffffffffffffffffffffffffff1663ed41d0b686866040518363ffffffff1660e01b815260040161148b929190613d26565b6020604051808303816000875af11580156114aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce91906135f6565b9050806114da57600080fd5b81156115d75760008081819054906101000a900460070b809291906114fe90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f60405161154f906134a3565b60006040518083038185875af1925050503d806000811461158c576040519150601f19603f3d011682016040523d82523d6000602084013e611591565b606091505b50509050806115d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115cc9061352a565b60405180910390fd5b505b5050505050565b600061080173ffffffffffffffffffffffffffffffffffffffff16632efe8a5f84846040518363ffffffff1660e01b815260040161161d929190613d4f565b6020604051808303816000875af115801561163c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166091906135f6565b905092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff16639ad563b484846040518363ffffffff1660e01b81526004016116a7929190613c55565b600060405180830381865afa1580156116c4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906116ed9190613d78565b905092915050565b600061080173ffffffffffffffffffffffffffffffffffffffff168383604051602401611723929190613c55565b6040516020818303038152906040527f5a9d9a96000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516117ad91906136ea565b600060405180830381855afa9150503d80600081146117e8576040519150601f19603f3d011682016040523d82523d6000602084013e6117ed565b606091505b5050905080611831576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118289061374d565b60405180910390fd5b505050565b606061080173ffffffffffffffffffffffffffffffffffffffff16633dd40f78836040518263ffffffff1660e01b815260040161187391906132b4565b600060405180830381865afa158015611890573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906118b99190613d78565b9050919050565b60606118ca6122d4565b61080173ffffffffffffffffffffffffffffffffffffffff16638f2473ce878787876040518563ffffffff1660e01b815260040161190b9493929190613f4c565b600060405180830381865afa158015611928573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906119519190614224565b9150915094509492505050565b600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9630846040518363ffffffff1660e01b815260040161199d929190613c55565b6020604051808303816000875af11580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e091906135f6565b9050919050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6184846040518363ffffffff1660e01b8152600401611a26929190613c55565b6000604051808303816000875af1158015611a45573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611a6e9190613c0c565b905092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6184846040518363ffffffff1660e01b8152600401611ab5929190613c55565b6000604051808303816000875af1158015611ad4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611afd9190613c0c565b600080fd5b60608215611c015760008081819054906101000a900460070b80929190611b2890613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f604051611b79906134a3565b60006040518083038185875af1925050503d8060008114611bb6576040519150601f19603f3d011682016040523d82523d6000602084013e611bbb565b606091505b5050905080611bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf69061352a565b60405180910390fd5b505b61080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6186866040518363ffffffff1660e01b8152600401611c3e929190613a8f565b6000604051808303816000875af1158015611c5d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611c869190613c0c565b90508115611d855760008081819054906101000a900460070b80929190611cac90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f604051611cfd906134a3565b60006040518083038185875af1925050503d8060008114611d3a576040519150601f19603f3d011682016040523d82523d6000602084013e611d3f565b606091505b5050905080611d83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7a9061352a565b60405180910390fd5b505b949350505050565b6060600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9633876040518363ffffffff1660e01b8152600401611dce929190613c55565b6020604051808303816000875af1158015611ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1191906135f6565b905080611e53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4a906142e8565b60405180910390fd5b61080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6185856040518363ffffffff1660e01b8152600401611e90929190613c55565b6000604051808303816000875af1158015611eaf573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ed89190613c0c565b9150509392505050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663a66cb605836040518263ffffffff1660e01b8152600401611f1f919061369e565b600060405180830381865afa158015611f3c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611f6591906143e9565b9050919050565b600060016000808282829054906101000a900460070b611f8c9190614432565b92506101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff16021790555061080173ffffffffffffffffffffffffffffffffffffffff1663ed41d0b684846040518363ffffffff1660e01b8152600401611ff2929190614492565b6020604051808303816000875af1158015612011573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203591906135f6565b905060016000808282829054906101000a900460070b61205591906144bb565b92506101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff16021790555092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff16635431f450836040518263ffffffff1660e01b81526004016120c1919061369e565b600060405180830381865afa1580156120de573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612107919061451b565b9050919050565b565b606061080173ffffffffffffffffffffffffffffffffffffffff166385b2d2da836040518263ffffffff1660e01b815260040161214d91906132b4565b600060405180830381865afa15801561216a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121939190613d78565b9050919050565b606061080173ffffffffffffffffffffffffffffffffffffffff16633ce4e3be836040518263ffffffff1660e01b81526004016121d791906132b4565b6000604051808303816000875af11580156121f6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061221f9190613c0c565b9050919050565b60608061080173ffffffffffffffffffffffffffffffffffffffff166354be1a28846040518263ffffffff1660e01b8152600401612264919061369e565b600060405180830381865afa158015612281573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122aa91906146cd565b91509150915091565b60405180606001604052806060815260200160608152602001606081525090565b604051806040016040528060608152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006123378261230c565b9050919050565b6123478161232c565b811461235257600080fd5b50565b6000813590506123648161233e565b92915050565b600063ffffffff82169050919050565b6123838161236a565b811461238e57600080fd5b50565b6000813590506123a08161237a565b92915050565b60008115159050919050565b6123bb816123a6565b81146123c657600080fd5b50565b6000813590506123d8816123b2565b92915050565b600080600080608085870312156123f8576123f7612302565b5b600061240687828801612355565b945050602061241787828801612391565b9350506040612428878288016123c9565b9250506060612439878288016123c9565b91505092959194509250565b60006124508261230c565b9050919050565b61246081612445565b811461246b57600080fd5b50565b60008135905061247d81612457565b92915050565b60006020828403121561249957612498612302565b5b60006124a78482850161246e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156124ea5780820151818401526020810190506124cf565b60008484015250505050565b6000601f19601f8301169050919050565b6000612512826124b0565b61251c81856124bb565b935061252c8185602086016124cc565b612535816124f6565b840191505092915050565b6000602082019050818103600083015261255a8184612507565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125a4826124f6565b810181811067ffffffffffffffff821117156125c3576125c261256c565b5b80604052505050565b60006125d66122f8565b90506125e2828261259b565b919050565b600067ffffffffffffffff8211156126025761260161256c565b5b61260b826124f6565b9050602081019050919050565b82818337600083830152505050565b600061263a612635846125e7565b6125cc565b90508281526020810184848401111561265657612655612567565b5b612661848285612618565b509392505050565b600082601f83011261267e5761267d612562565b5b813561268e848260208601612627565b91505092915050565b6000602082840312156126ad576126ac612302565b5b600082013567ffffffffffffffff8111156126cb576126ca612307565b5b6126d784828501612669565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000612707826126e0565b61271181856126eb565b93506127218185602086016124cc565b61272a816124f6565b840191505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b61277481612761565b82525050565b600060ff82169050919050565b6127908161277a565b82525050565b600060608301600083015184820360008601526127b382826126fc565b91505060208301516127c8602086018261276b565b5060408301516127db6040860182612787565b508091505092915050565b60006127f28383612796565b905092915050565b6000602082019050919050565b600061281282612735565b61281c8185612740565b93508360208202850161282e85612751565b8060005b8581101561286a578484038952815161284b85826127e6565b9450612856836127fa565b925060208a01995050600181019050612832565b50829750879550505050505092915050565b6000606083016000830151848203600086015261289982826126fc565b915050602083015184820360208601526128b38282612807565b915050604083015184820360408601526128cd8282612807565b9150508091505092915050565b600060208201905081810360008301526128f4818461287c565b905092915050565b6000806000806080858703121561291657612915612302565b5b600061292487828801612355565b945050602061293587828801612355565b935050604085013567ffffffffffffffff81111561295657612955612307565b5b61296287828801612669565b9250506060612973878288016123c9565b91505092959194509250565b6000806040838503121561299657612995612302565b5b60006129a48582860161246e565b925050602083013567ffffffffffffffff8111156129c5576129c4612307565b5b6129d185828601612669565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006040830160008301518482036000860152612a2482826126fc565b9150506020830151612a39602086018261276b565b508091505092915050565b6000612a508383612a07565b905092915050565b6000602082019050919050565b6000612a70826129db565b612a7a81856129e6565b935083602082028501612a8c856129f7565b8060005b85811015612ac85784840389528151612aa98582612a44565b9450612ab483612a58565b925060208a01995050600181019050612a90565b50829750879550505050505092915050565b60006020820190508181036000830152612af48184612a65565b905092915050565b612b05816123a6565b82525050565b6000602082019050612b206000830184612afc565b92915050565b60008060008060808587031215612b4057612b3f612302565b5b600085013567ffffffffffffffff811115612b5e57612b5d612307565b5b612b6a87828801612669565b9450506020612b7b87828801612355565b9350506040612b8c878288016123c9565b9250506060612b9d878288016123c9565b91505092959194509250565b60008160070b9050919050565b612bbf81612ba9565b82525050565b6000602082019050612bda6000830184612bb6565b92915050565b612be981612761565b8114612bf457600080fd5b50565b600081359050612c0681612be0565b92915050565b60008060008060808587031215612c2657612c25612302565b5b6000612c3487828801612355565b9450506020612c4587828801612bf7565b9350506040612c56878288016123c9565b9250506060612c67878288016123c9565b91505092959194509250565b60008060408385031215612c8a57612c89612302565b5b6000612c988582860161246e565b9250506020612ca985828601612391565b9150509250929050565b600082825260208201905092915050565b6000612ccf82612735565b612cd98185612cb3565b935083602082028501612ceb85612751565b8060005b85811015612d275784840389528151612d0885826127e6565b9450612d13836127fa565b925060208a01995050600181019050612cef565b50829750879550505050505092915050565b60006020820190508181036000830152612d538184612cc4565b905092915050565b600067ffffffffffffffff82169050919050565b612d7881612d5b565b8114612d8357600080fd5b50565b600081359050612d9581612d6f565b92915050565b600080fd5b600060a08284031215612db657612db5612d9b565b5b81905092915050565b60008060008060808587031215612dd957612dd8612302565b5b600085013567ffffffffffffffff811115612df757612df6612307565b5b612e0387828801612669565b9450506020612e1487828801612d86565b9350506040612e2587828801612d86565b925050606085013567ffffffffffffffff811115612e4657612e45612307565b5b612e5287828801612da0565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612e9381612d5b565b82525050565b604082016000820151612eaf600085018261276b565b506020820151612ec26020850182612787565b50505050565b606082016000820151612ede6000850182612e8a565b506020820151612ef16020850182612e99565b50505050565b6000612f038383612ec8565b60608301905092915050565b6000602082019050919050565b6000612f2782612e5e565b612f318185612e69565b9350612f3c83612e7a565b8060005b83811015612f6d578151612f548882612ef7565b9750612f5f83612f0f565b925050600181019050612f40565b5085935050505092915050565b600082825260208201905092915050565b6000612f96826124b0565b612fa08185612f7a565b9350612fb08185602086016124cc565b612fb9816124f6565b840191505092915050565b60006040830160008301518482036000860152612fe18282612f8b565b9150506020830151612ff66020860182612e8a565b508091505092915050565b6000604082019050818103600083015261301b8185612f1c565b9050818103602083015261302f8184612fc4565b90509392505050565b6000806000806080858703121561305257613051612302565b5b600061306087828801612355565b945050602085013567ffffffffffffffff81111561308157613080612307565b5b61308d87828801612669565b935050604061309e878288016123c9565b92505060606130af878288016123c9565b91505092959194509250565b6000806000606084860312156130d4576130d3612302565b5b600084013567ffffffffffffffff8111156130f2576130f1612307565b5b6130fe86828701612669565b935050602061310f8682870161246e565b925050604084013567ffffffffffffffff8111156131305761312f612307565b5b61313c86828701612669565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061317e83836126fc565b905092915050565b6000602082019050919050565b600061319e82613146565b6131a88185613151565b9350836020820285016131ba85613162565b8060005b858110156131f657848403895281516131d78582613172565b94506131e283613186565b925060208a019950506001810190506131be565b50829750879550505050505092915050565b600060208201905081810360008301526132228184613193565b905092915050565b6000806040838503121561324157613240612302565b5b600061324f8582860161246e565b925050602061326085828601612bf7565b9150509250929050565b600082825260208201905092915050565b6000613286826126e0565b613290818561326a565b93506132a08185602086016124cc565b6132a9816124f6565b840191505092915050565b600060208201905081810360008301526132ce818461327b565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000604083016000830151848203600086015261331f82826126fc565b915050602083015184820360208601526133398282612807565b9150508091505092915050565b60006133528383613302565b905092915050565b6000602082019050919050565b6000613372826132d6565b61337c81856132e1565b93508360208202850161338e856132f2565b8060005b858110156133ca57848403895281516133ab8582613346565b94506133b68361335a565b925060208a01995050600181019050613392565b50829750879550505050505092915050565b600060408201905081810360008301526133f68185613367565b9050818103602083015261340a8184612cc4565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061344d82612ba9565b9150677fffffffffffffff820361346757613466613413565b5b600182019050919050565b600081905092915050565b50565b600061348d600083613472565b91506134988261347d565b600082019050919050565b60006134ae82613480565b9150819050919050565b7f4661696c656420746f2073656e6420457468657220746f2064656c656761746f60008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061351460218361326a565b915061351f826134b8565b604082019050919050565b6000602082019050818103600083015261354381613507565b9050919050565b6000819050919050565b600061356f61356a6135658461230c565b61354a565b61230c565b9050919050565b600061358182613554565b9050919050565b600061359382613576565b9050919050565b6135a381613588565b82525050565b6135b28161236a565b82525050565b60006040820190506135cd600083018561359a565b6135da60208301846135a9565b9392505050565b6000815190506135f0816123b2565b92915050565b60006020828403121561360c5761360b612302565b5b600061361a848285016135e1565b91505092915050565b7f6661696c656420746f20636c61696d2072657761726473000000000000000000600082015250565b600061365960178361326a565b915061366482613623565b602082019050919050565b600060208201905081810360008301526136888161364c565b9050919050565b61369881612445565b82525050565b60006020820190506136b3600083018461368f565b92915050565b60006136c4826124b0565b6136ce8185613472565b93506136de8185602086016124cc565b80840191505092915050565b60006136f682846136b9565b915081905092915050565b7f6661696c65642073746174696343616c6c20746f20707265636f6d70696c6500600082015250565b6000613737601f8361326a565b915061374282613701565b602082019050919050565b600060208201905081810360008301526137668161372a565b9050919050565b600080fd5b600080fd5b600061378a613785846125e7565b6125cc565b9050828152602081018484840111156137a6576137a5612567565b5b6137b18482856124cc565b509392505050565b600082601f8301126137ce576137cd612562565b5b81516137de848260208601613777565b91505092915050565b600067ffffffffffffffff8211156138025761380161256c565b5b602082029050602081019050919050565b600080fd5b60008151905061382781612be0565b92915050565b6138368161277a565b811461384157600080fd5b50565b6000815190506138538161382d565b92915050565b60006060828403121561386f5761386e61376d565b5b61387960606125cc565b9050600082015167ffffffffffffffff81111561389957613898613772565b5b6138a5848285016137b9565b60008301525060206138b984828501613818565b60208301525060406138cd84828501613844565b60408301525092915050565b60006138ec6138e7846137e7565b6125cc565b9050808382526020820190506020840283018581111561390f5761390e613813565b5b835b8181101561395657805167ffffffffffffffff81111561393457613933612562565b5b8086016139418982613859565b85526020850194505050602081019050613911565b5050509392505050565b600082601f83011261397557613974612562565b5b81516139858482602086016138d9565b91505092915050565b6000606082840312156139a4576139a361376d565b5b6139ae60606125cc565b9050600082015167ffffffffffffffff8111156139ce576139cd613772565b5b6139da848285016137b9565b600083015250602082015167ffffffffffffffff8111156139fe576139fd613772565b5b613a0a84828501613960565b602083015250604082015167ffffffffffffffff811115613a2e57613a2d613772565b5b613a3a84828501613960565b60408301525092915050565b600060208284031215613a5c57613a5b612302565b5b600082015167ffffffffffffffff811115613a7a57613a79612307565b5b613a868482850161398e565b91505092915050565b6000604082019050613aa4600083018561359a565b8181036020830152613ab6818461327b565b90509392505050565b600067ffffffffffffffff821115613ada57613ad961256c565b5b602082029050602081019050919050565b600060408284031215613b0157613b0061376d565b5b613b0b60406125cc565b9050600082015167ffffffffffffffff811115613b2b57613b2a613772565b5b613b37848285016137b9565b6000830152506020613b4b84828501613818565b60208301525092915050565b6000613b6a613b6584613abf565b6125cc565b90508083825260208201905060208402830185811115613b8d57613b8c613813565b5b835b81811015613bd457805167ffffffffffffffff811115613bb257613bb1612562565b5b808601613bbf8982613aeb565b85526020850194505050602081019050613b8f565b5050509392505050565b600082601f830112613bf357613bf2612562565b5b8151613c03848260208601613b57565b91505092915050565b600060208284031215613c2257613c21612302565b5b600082015167ffffffffffffffff811115613c4057613c3f612307565b5b613c4c84828501613bde565b91505092915050565b6000604082019050613c6a600083018561368f565b8181036020830152613c7c818461327b565b90509392505050565b7f6661696c65642064656c656761746543616c6c20746f20707265636f6d70696c60008201527f6500000000000000000000000000000000000000000000000000000000000000602082015250565b6000613ce160218361326a565b9150613cec82613c85565b604082019050919050565b60006020820190508181036000830152613d1081613cd4565b9050919050565b613d2081612761565b82525050565b6000604082019050613d3b600083018561359a565b613d486020830184613d17565b9392505050565b6000604082019050613d64600083018561368f565b613d7160208301846135a9565b9392505050565b600060208284031215613d8e57613d8d612302565b5b600082015167ffffffffffffffff811115613dac57613dab612307565b5b613db884828501613960565b91505092915050565b613dca81612d5b565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112613dfc57613dfb613dda565b5b83810192508235915060208301925067ffffffffffffffff821115613e2457613e23613dd0565b5b600182023603831315613e3a57613e39613dd5565b5b509250929050565b6000613e4e8385612f7a565b9350613e5b838584612618565b613e64836124f6565b840190509392505050565b6000613e7e6020840184612d86565b905092915050565b6000613e9560208401846123c9565b905092915050565b613ea6816123a6565b82525050565b600060a08301613ebf6000840184613ddf565b8583036000870152613ed2838284613e42565b92505050613ee36020840184613e6f565b613ef06020860182612e8a565b50613efe6040840184613e6f565b613f0b6040860182612e8a565b50613f196060840184613e86565b613f266060860182613e9d565b50613f346080840184613e86565b613f416080860182613e9d565b508091505092915050565b60006080820190508181036000830152613f66818761327b565b9050613f756020830186613dc1565b613f826040830185613dc1565b8181036060830152613f948184613eac565b905095945050505050565b600067ffffffffffffffff821115613fba57613fb961256c565b5b602082029050602081019050919050565b600081519050613fda81612d6f565b92915050565b600060408284031215613ff657613ff561376d565b5b61400060406125cc565b9050600061401084828501613818565b600083015250602061402484828501613844565b60208301525092915050565b6000606082840312156140465761404561376d565b5b61405060406125cc565b9050600061406084828501613fcb565b600083015250602061407484828501613fe0565b60208301525092915050565b600061409361408e84613f9f565b6125cc565b905080838252602082019050606084028301858111156140b6576140b5613813565b5b835b818110156140df57806140cb8882614030565b8452602084019350506060810190506140b8565b5050509392505050565b600082601f8301126140fe576140fd612562565b5b815161410e848260208601614080565b91505092915050565b600067ffffffffffffffff8211156141325761413161256c565b5b61413b826124f6565b9050602081019050919050565b600061415b61415684614117565b6125cc565b90508281526020810184848401111561417757614176612567565b5b6141828482856124cc565b509392505050565b600082601f83011261419f5761419e612562565b5b81516141af848260208601614148565b91505092915050565b6000604082840312156141ce576141cd61376d565b5b6141d860406125cc565b9050600082015167ffffffffffffffff8111156141f8576141f7613772565b5b6142048482850161418a565b600083015250602061421884828501613fcb565b60208301525092915050565b6000806040838503121561423b5761423a612302565b5b600083015167ffffffffffffffff81111561425957614258612307565b5b614265858286016140e9565b925050602083015167ffffffffffffffff81111561428657614285612307565b5b614292858286016141b8565b9150509250929050565b7f6661696c656420746f2073657420776974686472617720616464726573730000600082015250565b60006142d2601e8361326a565b91506142dd8261429c565b602082019050919050565b60006020820190508181036000830152614301816142c5565b9050919050565b600067ffffffffffffffff8211156143235761432261256c565b5b602082029050602081019050919050565b600061434761434284614308565b6125cc565b9050808382526020820190506020840283018581111561436a57614369613813565b5b835b818110156143b157805167ffffffffffffffff81111561438f5761438e612562565b5b80860161439c89826137b9565b8552602085019450505060208101905061436c565b5050509392505050565b600082601f8301126143d0576143cf612562565b5b81516143e0848260208601614334565b91505092915050565b6000602082840312156143ff576143fe612302565b5b600082015167ffffffffffffffff81111561441d5761441c612307565b5b614429848285016143bb565b91505092915050565b600061443d82612ba9565b915061444883612ba9565b925082820190507fffffffffffffffffffffffffffffffffffffffffffffffff80000000000000008112677fffffffffffffff8213171561448c5761448b613413565b5b92915050565b60006040820190506144a7600083018561368f565b6144b46020830184613d17565b9392505050565b60006144c682612ba9565b91506144d183612ba9565b92508282039050677fffffffffffffff81137fffffffffffffffffffffffffffffffffffffffffffffffff80000000000000008212171561451557614514613413565b5b92915050565b60006020828403121561453157614530612302565b5b600082015167ffffffffffffffff81111561454f5761454e612307565b5b61455b848285016137b9565b91505092915050565b600067ffffffffffffffff82111561457f5761457e61256c565b5b602082029050602081019050919050565b6000604082840312156145a6576145a561376d565b5b6145b060406125cc565b9050600082015167ffffffffffffffff8111156145d0576145cf613772565b5b6145dc848285016137b9565b600083015250602082015167ffffffffffffffff811115614600576145ff613772565b5b61460c84828501613960565b60208301525092915050565b600061462b61462684614564565b6125cc565b9050808382526020820190506020840283018581111561464e5761464d613813565b5b835b8181101561469557805167ffffffffffffffff81111561467357614672612562565b5b8086016146808982614590565b85526020850194505050602081019050614650565b5050509392505050565b600082601f8301126146b4576146b3612562565b5b81516146c4848260208601614618565b91505092915050565b600080604083850312156146e4576146e3612302565b5b600083015167ffffffffffffffff81111561470257614701612307565b5b61470e8582860161469f565b925050602083015167ffffffffffffffff81111561472f5761472e612307565b5b61473b85828601613960565b915050925092905056fea26469706673582212207a2797e1368ab3a260b6425272925c564a5b3820d913462748338f0fc1b6822764736f6c63430008130033",
-  "deployedBytecode": "0x60806040526004361061019c5760003560e01c80637c9db0bb116100ec578063b6a216ae1161008a578063d0e30db011610064578063d0e30db0146106a7578063d3f831be146106b1578063e0421e39146106ee578063e236c7a61461072b5761019c565b8063b6a216ae146105f0578063c7804bb51461062d578063cb85aa0a1461066a5761019c565b806398194593116100c657806398194593146104fc578063ad5c4cdd14610539578063adb2378514610576578063b2d17883146105b35761019c565b80637c9db0bb1461044457806388b2d58114610481578063963516e4146104bf5761019c565b806346e16d34116101595780636cc9ac8a116101335780636cc9ac8a146103785780636f669da4146103a157806378a5dfd1146103de578063796b96d21461041b5761019c565b806346e16d34146102d3578063613d4de81461031057806361bc221a1461034d5761019c565b80630183e4b4146101a157806301b68000146101ca5780630c05e9e4146102075780631b05020714610244578063296c60aa1461026d5780632d0ee16a14610296575b600080fd5b3480156101ad57600080fd5b506101c860048036038101906101c391906123de565b610769565b005b3480156101d657600080fd5b506101f160048036038101906101ec9190612483565b610a96565b6040516101fe9190612540565b60405180910390f35b34801561021357600080fd5b5061022e60048036038101906102299190612697565b610bde565b60405161023b91906128da565b60405180910390f35b34801561025057600080fd5b5061026b600480360381019061026691906128fc565b610c6e565b005b34801561027957600080fd5b50610294600480360381019061028f919061297f565b610df4565b005b3480156102a257600080fd5b506102bd60048036038101906102b89190612697565b610f35565b6040516102ca9190612ada565b60405180910390f35b3480156102df57600080fd5b506102fa60048036038101906102f5919061297f565b610fc3565b6040516103079190612b0b565b60405180910390f35b34801561031c57600080fd5b5061033760048036038101906103329190612b26565b61104d565b6040516103449190612ada565b60405180910390f35b34801561035957600080fd5b5061036261133e565b60405161036f9190612bc5565b60405180910390f35b34801561038457600080fd5b5061039f600480360381019061039a9190612c0c565b61134f565b005b3480156103ad57600080fd5b506103c860048036038101906103c39190612c73565b6115de565b6040516103d59190612b0b565b60405180910390f35b3480156103ea57600080fd5b506104056004803603810190610400919061297f565b611668565b6040516104129190612d39565b60405180910390f35b34801561042757600080fd5b50610442600480360381019061043d919061297f565b6116f5565b005b34801561045057600080fd5b5061046b60048036038101906104669190612697565b611836565b6040516104789190612d39565b60405180910390f35b34801561048d57600080fd5b506104a860048036038101906104a39190612dbf565b6118c0565b6040516104b6929190613001565b60405180910390f35b3480156104cb57600080fd5b506104e660048036038101906104e19190612697565b61195e565b6040516104f39190612b0b565b60405180910390f35b34801561050857600080fd5b50610523600480360381019061051e919061297f565b6119e7565b6040516105309190612ada565b60405180910390f35b34801561054557600080fd5b50610560600480360381019061055b919061297f565b611a76565b60405161056d9190612ada565b60405180910390f35b34801561058257600080fd5b5061059d60048036038101906105989190613038565b611b02565b6040516105aa9190612ada565b60405180910390f35b3480156105bf57600080fd5b506105da60048036038101906105d591906130bb565b611d8d565b6040516105e79190612ada565b60405180910390f35b3480156105fc57600080fd5b5061061760048036038101906106129190612483565b611ee2565b6040516106249190613208565b60405180910390f35b34801561063957600080fd5b50610654600480360381019061064f919061322a565b611f6c565b6040516106619190612b0b565b60405180910390f35b34801561067657600080fd5b50610691600480360381019061068c9190612483565b612084565b60405161069e91906132b4565b60405180910390f35b6106af61210e565b005b3480156106bd57600080fd5b506106d860048036038101906106d39190612697565b612110565b6040516106e59190612d39565b60405180910390f35b3480156106fa57600080fd5b5061071560048036038101906107109190612697565b61219a565b6040516107229190612ada565b60405180910390f35b34801561073757600080fd5b50610752600480360381019061074d9190612483565b612226565b6040516107609291906133dc565b60405180910390f35b811561089a5760008081819054906101000a900460070b8092919061078d90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146108995760008473ffffffffffffffffffffffffffffffffffffffff16600f604051610811906134a3565b60006040518083038185875af1925050503d806000811461084e576040519150601f19603f3d011682016040523d82523d6000602084013e610853565b606091505b5050905080610897576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088e9061352a565b60405180910390fd5b505b5b600061080173ffffffffffffffffffffffffffffffffffffffff16632efe8a5f86866040518363ffffffff1660e01b81526004016108d99291906135b8565b6020604051808303816000875af11580156108f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091c91906135f6565b90508061095e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061366f565b60405180910390fd5b8115610a8f5760008081819054906101000a900460070b8092919061098290613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610a8e5760008573ffffffffffffffffffffffffffffffffffffffff16600f604051610a06906134a3565b60006040518083038185875af1925050503d8060008114610a43576040519150601f19603f3d011682016040523d82523d6000602084013e610a48565b606091505b5050905080610a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a839061352a565b60405180910390fd5b505b5b5050505050565b606060008061080173ffffffffffffffffffffffffffffffffffffffff1684604051602401610ac5919061369e565b6040516020818303038152906040527f5431f450000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610b4f91906136ea565b600060405180830381855afa9150503d8060008114610b8a576040519150601f19603f3d011682016040523d82523d6000602084013e610b8f565b606091505b509150915081610bd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcb9061374d565b60405180910390fd5b8092505050919050565b610be66122b3565b61080173ffffffffffffffffffffffffffffffffffffffff166354212a89836040518263ffffffff1660e01b8152600401610c2191906132b4565b600060405180830381865afa158015610c3e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610c679190613a46565b9050919050565b3073ffffffffffffffffffffffffffffffffffffffff1663ad5c4cdd85846040518363ffffffff1660e01b8152600401610ca9929190613a8f565b6000604051808303816000875af1925050508015610cea57506040513d6000823e3d601f19601f82011682018060405250810190610ce79190613c0c565b60015b15610cf157505b8015610dee5760008081819054906101000a900460070b80929190610d1590613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008373ffffffffffffffffffffffffffffffffffffffff16600f604051610d66906134a3565b60006040518083038185875af1925050503d8060008114610da3576040519150601f19603f3d011682016040523d82523d6000602084013e610da8565b606091505b5050905080610dec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de39061352a565b60405180910390fd5b505b50505050565b600061080173ffffffffffffffffffffffffffffffffffffffff168383604051602401610e22929190613c55565b6040516020818303038152906040527f5a9d9a96000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610eac91906136ea565b600060405180830381855af49150503d8060008114610ee7576040519150601f19603f3d011682016040523d82523d6000602084013e610eec565b606091505b5050905080610f30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2790613cf7565b60405180910390fd5b505050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6130846040518363ffffffff1660e01b8152600401610f74929190613c55565b6000604051808303816000875af1158015610f93573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610fbc9190613c0c565b9050919050565b600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9684846040518363ffffffff1660e01b8152600401611002929190613c55565b6020604051808303816000875af1158015611021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104591906135f6565b905092915050565b606082156111805760008081819054906101000a900460070b8092919061107390613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461117f5760008473ffffffffffffffffffffffffffffffffffffffff16600f6040516110f7906134a3565b60006040518083038185875af1925050503d8060008114611134576040519150601f19603f3d011682016040523d82523d6000602084013e611139565b606091505b505090508061117d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111749061352a565b60405180910390fd5b505b5b61080173ffffffffffffffffffffffffffffffffffffffff16633ce4e3be866040518263ffffffff1660e01b81526004016111bb91906132b4565b6000604051808303816000875af11580156111da573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112039190613c0c565b905081156113365760008081819054906101000a900460070b8092919061122990613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146113355760008473ffffffffffffffffffffffffffffffffffffffff16600f6040516112ad906134a3565b60006040518083038185875af1925050503d80600081146112ea576040519150601f19603f3d011682016040523d82523d6000602084013e6112ef565b606091505b5050905080611333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132a9061352a565b60405180910390fd5b505b5b949350505050565b60008054906101000a900460070b81565b811561144c5760008081819054906101000a900460070b8092919061137390613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008473ffffffffffffffffffffffffffffffffffffffff16600f6040516113c4906134a3565b60006040518083038185875af1925050503d8060008114611401576040519150601f19603f3d011682016040523d82523d6000602084013e611406565b606091505b505090508061144a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114419061352a565b60405180910390fd5b505b600061080173ffffffffffffffffffffffffffffffffffffffff1663ed41d0b686866040518363ffffffff1660e01b815260040161148b929190613d26565b6020604051808303816000875af11580156114aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce91906135f6565b9050806114da57600080fd5b81156115d75760008081819054906101000a900460070b809291906114fe90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f60405161154f906134a3565b60006040518083038185875af1925050503d806000811461158c576040519150601f19603f3d011682016040523d82523d6000602084013e611591565b606091505b50509050806115d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115cc9061352a565b60405180910390fd5b505b5050505050565b600061080173ffffffffffffffffffffffffffffffffffffffff16632efe8a5f84846040518363ffffffff1660e01b815260040161161d929190613d4f565b6020604051808303816000875af115801561163c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166091906135f6565b905092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff16639ad563b484846040518363ffffffff1660e01b81526004016116a7929190613c55565b600060405180830381865afa1580156116c4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906116ed9190613d78565b905092915050565b600061080173ffffffffffffffffffffffffffffffffffffffff168383604051602401611723929190613c55565b6040516020818303038152906040527f5a9d9a96000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516117ad91906136ea565b600060405180830381855afa9150503d80600081146117e8576040519150601f19603f3d011682016040523d82523d6000602084013e6117ed565b606091505b5050905080611831576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118289061374d565b60405180910390fd5b505050565b606061080173ffffffffffffffffffffffffffffffffffffffff16633dd40f78836040518263ffffffff1660e01b815260040161187391906132b4565b600060405180830381865afa158015611890573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906118b99190613d78565b9050919050565b60606118ca6122d4565b61080173ffffffffffffffffffffffffffffffffffffffff16638f2473ce878787876040518563ffffffff1660e01b815260040161190b9493929190613f4c565b600060405180830381865afa158015611928573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906119519190614224565b9150915094509492505050565b600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9630846040518363ffffffff1660e01b815260040161199d929190613c55565b6020604051808303816000875af11580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e091906135f6565b9050919050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6184846040518363ffffffff1660e01b8152600401611a26929190613c55565b6000604051808303816000875af1158015611a45573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611a6e9190613c0c565b905092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6184846040518363ffffffff1660e01b8152600401611ab5929190613c55565b6000604051808303816000875af1158015611ad4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611afd9190613c0c565b600080fd5b60608215611c015760008081819054906101000a900460070b80929190611b2890613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f604051611b79906134a3565b60006040518083038185875af1925050503d8060008114611bb6576040519150601f19603f3d011682016040523d82523d6000602084013e611bbb565b606091505b5050905080611bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf69061352a565b60405180910390fd5b505b61080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6186866040518363ffffffff1660e01b8152600401611c3e929190613a8f565b6000604051808303816000875af1158015611c5d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611c869190613c0c565b90508115611d855760008081819054906101000a900460070b80929190611cac90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f604051611cfd906134a3565b60006040518083038185875af1925050503d8060008114611d3a576040519150601f19603f3d011682016040523d82523d6000602084013e611d3f565b606091505b5050905080611d83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7a9061352a565b60405180910390fd5b505b949350505050565b6060600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9633876040518363ffffffff1660e01b8152600401611dce929190613c55565b6020604051808303816000875af1158015611ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1191906135f6565b905080611e53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4a906142e8565b60405180910390fd5b61080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6185856040518363ffffffff1660e01b8152600401611e90929190613c55565b6000604051808303816000875af1158015611eaf573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ed89190613c0c565b9150509392505050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663a66cb605836040518263ffffffff1660e01b8152600401611f1f919061369e565b600060405180830381865afa158015611f3c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611f6591906143e9565b9050919050565b600060016000808282829054906101000a900460070b611f8c9190614432565b92506101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff16021790555061080173ffffffffffffffffffffffffffffffffffffffff1663ed41d0b684846040518363ffffffff1660e01b8152600401611ff2929190614492565b6020604051808303816000875af1158015612011573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203591906135f6565b905060016000808282829054906101000a900460070b61205591906144bb565b92506101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff16021790555092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff16635431f450836040518263ffffffff1660e01b81526004016120c1919061369e565b600060405180830381865afa1580156120de573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612107919061451b565b9050919050565b565b606061080173ffffffffffffffffffffffffffffffffffffffff166385b2d2da836040518263ffffffff1660e01b815260040161214d91906132b4565b600060405180830381865afa15801561216a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121939190613d78565b9050919050565b606061080173ffffffffffffffffffffffffffffffffffffffff16633ce4e3be836040518263ffffffff1660e01b81526004016121d791906132b4565b6000604051808303816000875af11580156121f6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061221f9190613c0c565b9050919050565b60608061080173ffffffffffffffffffffffffffffffffffffffff166354be1a28846040518263ffffffff1660e01b8152600401612264919061369e565b600060405180830381865afa158015612281573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122aa91906146cd565b91509150915091565b60405180606001604052806060815260200160608152602001606081525090565b604051806040016040528060608152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006123378261230c565b9050919050565b6123478161232c565b811461235257600080fd5b50565b6000813590506123648161233e565b92915050565b600063ffffffff82169050919050565b6123838161236a565b811461238e57600080fd5b50565b6000813590506123a08161237a565b92915050565b60008115159050919050565b6123bb816123a6565b81146123c657600080fd5b50565b6000813590506123d8816123b2565b92915050565b600080600080608085870312156123f8576123f7612302565b5b600061240687828801612355565b945050602061241787828801612391565b9350506040612428878288016123c9565b9250506060612439878288016123c9565b91505092959194509250565b60006124508261230c565b9050919050565b61246081612445565b811461246b57600080fd5b50565b60008135905061247d81612457565b92915050565b60006020828403121561249957612498612302565b5b60006124a78482850161246e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156124ea5780820151818401526020810190506124cf565b60008484015250505050565b6000601f19601f8301169050919050565b6000612512826124b0565b61251c81856124bb565b935061252c8185602086016124cc565b612535816124f6565b840191505092915050565b6000602082019050818103600083015261255a8184612507565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125a4826124f6565b810181811067ffffffffffffffff821117156125c3576125c261256c565b5b80604052505050565b60006125d66122f8565b90506125e2828261259b565b919050565b600067ffffffffffffffff8211156126025761260161256c565b5b61260b826124f6565b9050602081019050919050565b82818337600083830152505050565b600061263a612635846125e7565b6125cc565b90508281526020810184848401111561265657612655612567565b5b612661848285612618565b509392505050565b600082601f83011261267e5761267d612562565b5b813561268e848260208601612627565b91505092915050565b6000602082840312156126ad576126ac612302565b5b600082013567ffffffffffffffff8111156126cb576126ca612307565b5b6126d784828501612669565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000612707826126e0565b61271181856126eb565b93506127218185602086016124cc565b61272a816124f6565b840191505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b61277481612761565b82525050565b600060ff82169050919050565b6127908161277a565b82525050565b600060608301600083015184820360008601526127b382826126fc565b91505060208301516127c8602086018261276b565b5060408301516127db6040860182612787565b508091505092915050565b60006127f28383612796565b905092915050565b6000602082019050919050565b600061281282612735565b61281c8185612740565b93508360208202850161282e85612751565b8060005b8581101561286a578484038952815161284b85826127e6565b9450612856836127fa565b925060208a01995050600181019050612832565b50829750879550505050505092915050565b6000606083016000830151848203600086015261289982826126fc565b915050602083015184820360208601526128b38282612807565b915050604083015184820360408601526128cd8282612807565b9150508091505092915050565b600060208201905081810360008301526128f4818461287c565b905092915050565b6000806000806080858703121561291657612915612302565b5b600061292487828801612355565b945050602061293587828801612355565b935050604085013567ffffffffffffffff81111561295657612955612307565b5b61296287828801612669565b9250506060612973878288016123c9565b91505092959194509250565b6000806040838503121561299657612995612302565b5b60006129a48582860161246e565b925050602083013567ffffffffffffffff8111156129c5576129c4612307565b5b6129d185828601612669565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006040830160008301518482036000860152612a2482826126fc565b9150506020830151612a39602086018261276b565b508091505092915050565b6000612a508383612a07565b905092915050565b6000602082019050919050565b6000612a70826129db565b612a7a81856129e6565b935083602082028501612a8c856129f7565b8060005b85811015612ac85784840389528151612aa98582612a44565b9450612ab483612a58565b925060208a01995050600181019050612a90565b50829750879550505050505092915050565b60006020820190508181036000830152612af48184612a65565b905092915050565b612b05816123a6565b82525050565b6000602082019050612b206000830184612afc565b92915050565b60008060008060808587031215612b4057612b3f612302565b5b600085013567ffffffffffffffff811115612b5e57612b5d612307565b5b612b6a87828801612669565b9450506020612b7b87828801612355565b9350506040612b8c878288016123c9565b9250506060612b9d878288016123c9565b91505092959194509250565b60008160070b9050919050565b612bbf81612ba9565b82525050565b6000602082019050612bda6000830184612bb6565b92915050565b612be981612761565b8114612bf457600080fd5b50565b600081359050612c0681612be0565b92915050565b60008060008060808587031215612c2657612c25612302565b5b6000612c3487828801612355565b9450506020612c4587828801612bf7565b9350506040612c56878288016123c9565b9250506060612c67878288016123c9565b91505092959194509250565b60008060408385031215612c8a57612c89612302565b5b6000612c988582860161246e565b9250506020612ca985828601612391565b9150509250929050565b600082825260208201905092915050565b6000612ccf82612735565b612cd98185612cb3565b935083602082028501612ceb85612751565b8060005b85811015612d275784840389528151612d0885826127e6565b9450612d13836127fa565b925060208a01995050600181019050612cef565b50829750879550505050505092915050565b60006020820190508181036000830152612d538184612cc4565b905092915050565b600067ffffffffffffffff82169050919050565b612d7881612d5b565b8114612d8357600080fd5b50565b600081359050612d9581612d6f565b92915050565b600080fd5b600060a08284031215612db657612db5612d9b565b5b81905092915050565b60008060008060808587031215612dd957612dd8612302565b5b600085013567ffffffffffffffff811115612df757612df6612307565b5b612e0387828801612669565b9450506020612e1487828801612d86565b9350506040612e2587828801612d86565b925050606085013567ffffffffffffffff811115612e4657612e45612307565b5b612e5287828801612da0565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612e9381612d5b565b82525050565b604082016000820151612eaf600085018261276b565b506020820151612ec26020850182612787565b50505050565b606082016000820151612ede6000850182612e8a565b506020820151612ef16020850182612e99565b50505050565b6000612f038383612ec8565b60608301905092915050565b6000602082019050919050565b6000612f2782612e5e565b612f318185612e69565b9350612f3c83612e7a565b8060005b83811015612f6d578151612f548882612ef7565b9750612f5f83612f0f565b925050600181019050612f40565b5085935050505092915050565b600082825260208201905092915050565b6000612f96826124b0565b612fa08185612f7a565b9350612fb08185602086016124cc565b612fb9816124f6565b840191505092915050565b60006040830160008301518482036000860152612fe18282612f8b565b9150506020830151612ff66020860182612e8a565b508091505092915050565b6000604082019050818103600083015261301b8185612f1c565b9050818103602083015261302f8184612fc4565b90509392505050565b6000806000806080858703121561305257613051612302565b5b600061306087828801612355565b945050602085013567ffffffffffffffff81111561308157613080612307565b5b61308d87828801612669565b935050604061309e878288016123c9565b92505060606130af878288016123c9565b91505092959194509250565b6000806000606084860312156130d4576130d3612302565b5b600084013567ffffffffffffffff8111156130f2576130f1612307565b5b6130fe86828701612669565b935050602061310f8682870161246e565b925050604084013567ffffffffffffffff8111156131305761312f612307565b5b61313c86828701612669565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061317e83836126fc565b905092915050565b6000602082019050919050565b600061319e82613146565b6131a88185613151565b9350836020820285016131ba85613162565b8060005b858110156131f657848403895281516131d78582613172565b94506131e283613186565b925060208a019950506001810190506131be565b50829750879550505050505092915050565b600060208201905081810360008301526132228184613193565b905092915050565b6000806040838503121561324157613240612302565b5b600061324f8582860161246e565b925050602061326085828601612bf7565b9150509250929050565b600082825260208201905092915050565b6000613286826126e0565b613290818561326a565b93506132a08185602086016124cc565b6132a9816124f6565b840191505092915050565b600060208201905081810360008301526132ce818461327b565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000604083016000830151848203600086015261331f82826126fc565b915050602083015184820360208601526133398282612807565b9150508091505092915050565b60006133528383613302565b905092915050565b6000602082019050919050565b6000613372826132d6565b61337c81856132e1565b93508360208202850161338e856132f2565b8060005b858110156133ca57848403895281516133ab8582613346565b94506133b68361335a565b925060208a01995050600181019050613392565b50829750879550505050505092915050565b600060408201905081810360008301526133f68185613367565b9050818103602083015261340a8184612cc4565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061344d82612ba9565b9150677fffffffffffffff820361346757613466613413565b5b600182019050919050565b600081905092915050565b50565b600061348d600083613472565b91506134988261347d565b600082019050919050565b60006134ae82613480565b9150819050919050565b7f4661696c656420746f2073656e6420457468657220746f2064656c656761746f60008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061351460218361326a565b915061351f826134b8565b604082019050919050565b6000602082019050818103600083015261354381613507565b9050919050565b6000819050919050565b600061356f61356a6135658461230c565b61354a565b61230c565b9050919050565b600061358182613554565b9050919050565b600061359382613576565b9050919050565b6135a381613588565b82525050565b6135b28161236a565b82525050565b60006040820190506135cd600083018561359a565b6135da60208301846135a9565b9392505050565b6000815190506135f0816123b2565b92915050565b60006020828403121561360c5761360b612302565b5b600061361a848285016135e1565b91505092915050565b7f6661696c656420746f20636c61696d2072657761726473000000000000000000600082015250565b600061365960178361326a565b915061366482613623565b602082019050919050565b600060208201905081810360008301526136888161364c565b9050919050565b61369881612445565b82525050565b60006020820190506136b3600083018461368f565b92915050565b60006136c4826124b0565b6136ce8185613472565b93506136de8185602086016124cc565b80840191505092915050565b60006136f682846136b9565b915081905092915050565b7f6661696c65642073746174696343616c6c20746f20707265636f6d70696c6500600082015250565b6000613737601f8361326a565b915061374282613701565b602082019050919050565b600060208201905081810360008301526137668161372a565b9050919050565b600080fd5b600080fd5b600061378a613785846125e7565b6125cc565b9050828152602081018484840111156137a6576137a5612567565b5b6137b18482856124cc565b509392505050565b600082601f8301126137ce576137cd612562565b5b81516137de848260208601613777565b91505092915050565b600067ffffffffffffffff8211156138025761380161256c565b5b602082029050602081019050919050565b600080fd5b60008151905061382781612be0565b92915050565b6138368161277a565b811461384157600080fd5b50565b6000815190506138538161382d565b92915050565b60006060828403121561386f5761386e61376d565b5b61387960606125cc565b9050600082015167ffffffffffffffff81111561389957613898613772565b5b6138a5848285016137b9565b60008301525060206138b984828501613818565b60208301525060406138cd84828501613844565b60408301525092915050565b60006138ec6138e7846137e7565b6125cc565b9050808382526020820190506020840283018581111561390f5761390e613813565b5b835b8181101561395657805167ffffffffffffffff81111561393457613933612562565b5b8086016139418982613859565b85526020850194505050602081019050613911565b5050509392505050565b600082601f83011261397557613974612562565b5b81516139858482602086016138d9565b91505092915050565b6000606082840312156139a4576139a361376d565b5b6139ae60606125cc565b9050600082015167ffffffffffffffff8111156139ce576139cd613772565b5b6139da848285016137b9565b600083015250602082015167ffffffffffffffff8111156139fe576139fd613772565b5b613a0a84828501613960565b602083015250604082015167ffffffffffffffff811115613a2e57613a2d613772565b5b613a3a84828501613960565b60408301525092915050565b600060208284031215613a5c57613a5b612302565b5b600082015167ffffffffffffffff811115613a7a57613a79612307565b5b613a868482850161398e565b91505092915050565b6000604082019050613aa4600083018561359a565b8181036020830152613ab6818461327b565b90509392505050565b600067ffffffffffffffff821115613ada57613ad961256c565b5b602082029050602081019050919050565b600060408284031215613b0157613b0061376d565b5b613b0b60406125cc565b9050600082015167ffffffffffffffff811115613b2b57613b2a613772565b5b613b37848285016137b9565b6000830152506020613b4b84828501613818565b60208301525092915050565b6000613b6a613b6584613abf565b6125cc565b90508083825260208201905060208402830185811115613b8d57613b8c613813565b5b835b81811015613bd457805167ffffffffffffffff811115613bb257613bb1612562565b5b808601613bbf8982613aeb565b85526020850194505050602081019050613b8f565b5050509392505050565b600082601f830112613bf357613bf2612562565b5b8151613c03848260208601613b57565b91505092915050565b600060208284031215613c2257613c21612302565b5b600082015167ffffffffffffffff811115613c4057613c3f612307565b5b613c4c84828501613bde565b91505092915050565b6000604082019050613c6a600083018561368f565b8181036020830152613c7c818461327b565b90509392505050565b7f6661696c65642064656c656761746543616c6c20746f20707265636f6d70696c60008201527f6500000000000000000000000000000000000000000000000000000000000000602082015250565b6000613ce160218361326a565b9150613cec82613c85565b604082019050919050565b60006020820190508181036000830152613d1081613cd4565b9050919050565b613d2081612761565b82525050565b6000604082019050613d3b600083018561359a565b613d486020830184613d17565b9392505050565b6000604082019050613d64600083018561368f565b613d7160208301846135a9565b9392505050565b600060208284031215613d8e57613d8d612302565b5b600082015167ffffffffffffffff811115613dac57613dab612307565b5b613db884828501613960565b91505092915050565b613dca81612d5b565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112613dfc57613dfb613dda565b5b83810192508235915060208301925067ffffffffffffffff821115613e2457613e23613dd0565b5b600182023603831315613e3a57613e39613dd5565b5b509250929050565b6000613e4e8385612f7a565b9350613e5b838584612618565b613e64836124f6565b840190509392505050565b6000613e7e6020840184612d86565b905092915050565b6000613e9560208401846123c9565b905092915050565b613ea6816123a6565b82525050565b600060a08301613ebf6000840184613ddf565b8583036000870152613ed2838284613e42565b92505050613ee36020840184613e6f565b613ef06020860182612e8a565b50613efe6040840184613e6f565b613f0b6040860182612e8a565b50613f196060840184613e86565b613f266060860182613e9d565b50613f346080840184613e86565b613f416080860182613e9d565b508091505092915050565b60006080820190508181036000830152613f66818761327b565b9050613f756020830186613dc1565b613f826040830185613dc1565b8181036060830152613f948184613eac565b905095945050505050565b600067ffffffffffffffff821115613fba57613fb961256c565b5b602082029050602081019050919050565b600081519050613fda81612d6f565b92915050565b600060408284031215613ff657613ff561376d565b5b61400060406125cc565b9050600061401084828501613818565b600083015250602061402484828501613844565b60208301525092915050565b6000606082840312156140465761404561376d565b5b61405060406125cc565b9050600061406084828501613fcb565b600083015250602061407484828501613fe0565b60208301525092915050565b600061409361408e84613f9f565b6125cc565b905080838252602082019050606084028301858111156140b6576140b5613813565b5b835b818110156140df57806140cb8882614030565b8452602084019350506060810190506140b8565b5050509392505050565b600082601f8301126140fe576140fd612562565b5b815161410e848260208601614080565b91505092915050565b600067ffffffffffffffff8211156141325761413161256c565b5b61413b826124f6565b9050602081019050919050565b600061415b61415684614117565b6125cc565b90508281526020810184848401111561417757614176612567565b5b6141828482856124cc565b509392505050565b600082601f83011261419f5761419e612562565b5b81516141af848260208601614148565b91505092915050565b6000604082840312156141ce576141cd61376d565b5b6141d860406125cc565b9050600082015167ffffffffffffffff8111156141f8576141f7613772565b5b6142048482850161418a565b600083015250602061421884828501613fcb565b60208301525092915050565b6000806040838503121561423b5761423a612302565b5b600083015167ffffffffffffffff81111561425957614258612307565b5b614265858286016140e9565b925050602083015167ffffffffffffffff81111561428657614285612307565b5b614292858286016141b8565b9150509250929050565b7f6661696c656420746f2073657420776974686472617720616464726573730000600082015250565b60006142d2601e8361326a565b91506142dd8261429c565b602082019050919050565b60006020820190508181036000830152614301816142c5565b9050919050565b600067ffffffffffffffff8211156143235761432261256c565b5b602082029050602081019050919050565b600061434761434284614308565b6125cc565b9050808382526020820190506020840283018581111561436a57614369613813565b5b835b818110156143b157805167ffffffffffffffff81111561438f5761438e612562565b5b80860161439c89826137b9565b8552602085019450505060208101905061436c565b5050509392505050565b600082601f8301126143d0576143cf612562565b5b81516143e0848260208601614334565b91505092915050565b6000602082840312156143ff576143fe612302565b5b600082015167ffffffffffffffff81111561441d5761441c612307565b5b614429848285016143bb565b91505092915050565b600061443d82612ba9565b915061444883612ba9565b925082820190507fffffffffffffffffffffffffffffffffffffffffffffffff80000000000000008112677fffffffffffffff8213171561448c5761448b613413565b5b92915050565b60006040820190506144a7600083018561368f565b6144b46020830184613d17565b9392505050565b60006144c682612ba9565b91506144d183612ba9565b92508282039050677fffffffffffffff81137fffffffffffffffffffffffffffffffffffffffffffffffff80000000000000008212171561451557614514613413565b5b92915050565b60006020828403121561453157614530612302565b5b600082015167ffffffffffffffff81111561454f5761454e612307565b5b61455b848285016137b9565b91505092915050565b600067ffffffffffffffff82111561457f5761457e61256c565b5b602082029050602081019050919050565b6000604082840312156145a6576145a561376d565b5b6145b060406125cc565b9050600082015167ffffffffffffffff8111156145d0576145cf613772565b5b6145dc848285016137b9565b600083015250602082015167ffffffffffffffff811115614600576145ff613772565b5b61460c84828501613960565b60208301525092915050565b600061462b61462684614564565b6125cc565b9050808382526020820190506020840283018581111561464e5761464d613813565b5b835b8181101561469557805167ffffffffffffffff81111561467357614672612562565b5b8086016146808982614590565b85526020850194505050602081019050614650565b5050509392505050565b600082601f8301126146b4576146b3612562565b5b81516146c4848260208601614618565b91505092915050565b600080604083850312156146e4576146e3612302565b5b600083015167ffffffffffffffff81111561470257614701612307565b5b61470e8582860161469f565b925050602083015167ffffffffffffffff81111561472f5761472e612307565b5b61473b85828601613960565b915050925092905056fea26469706673582212207a2797e1368ab3a260b6425272925c564a5b3820d913462748338f0fc1b6822764736f6c63430008130033",
+  "bytecode": "0x608060405234801561001057600080fd5b5061477b806100206000396000f3fe60806040526004361061019c5760003560e01c80637c9db0bb116100ec578063b6a216ae1161008a578063d0e30db011610064578063d0e30db0146106a7578063d3f831be146106b1578063e0421e39146106ee578063e236c7a61461072b5761019c565b8063b6a216ae146105f0578063c7804bb51461062d578063cb85aa0a1461066a5761019c565b806398194593116100c657806398194593146104fc578063ad5c4cdd14610539578063adb2378514610576578063b2d17883146105b35761019c565b80637c9db0bb1461044457806388b2d58114610481578063963516e4146104bf5761019c565b806346e16d34116101595780636cc9ac8a116101335780636cc9ac8a146103785780636f669da4146103a157806378a5dfd1146103de578063796b96d21461041b5761019c565b806346e16d34146102d3578063613d4de81461031057806361bc221a1461034d5761019c565b80630183e4b4146101a157806301b68000146101ca5780630c05e9e4146102075780631b05020714610244578063296c60aa1461026d5780632d0ee16a14610296575b600080fd5b3480156101ad57600080fd5b506101c860048036038101906101c391906123de565b610769565b005b3480156101d657600080fd5b506101f160048036038101906101ec9190612483565b610a96565b6040516101fe9190612540565b60405180910390f35b34801561021357600080fd5b5061022e60048036038101906102299190612697565b610bde565b60405161023b91906128da565b60405180910390f35b34801561025057600080fd5b5061026b600480360381019061026691906128fc565b610c6e565b005b34801561027957600080fd5b50610294600480360381019061028f919061297f565b610df4565b005b3480156102a257600080fd5b506102bd60048036038101906102b89190612697565b610f35565b6040516102ca9190612ada565b60405180910390f35b3480156102df57600080fd5b506102fa60048036038101906102f5919061297f565b610fc3565b6040516103079190612b0b565b60405180910390f35b34801561031c57600080fd5b5061033760048036038101906103329190612b26565b61104d565b6040516103449190612ada565b60405180910390f35b34801561035957600080fd5b5061036261133e565b60405161036f9190612bc5565b60405180910390f35b34801561038457600080fd5b5061039f600480360381019061039a9190612c0c565b61134f565b005b3480156103ad57600080fd5b506103c860048036038101906103c39190612c73565b6115de565b6040516103d59190612b0b565b60405180910390f35b3480156103ea57600080fd5b506104056004803603810190610400919061297f565b611668565b6040516104129190612d39565b60405180910390f35b34801561042757600080fd5b50610442600480360381019061043d919061297f565b6116f5565b005b34801561045057600080fd5b5061046b60048036038101906104669190612697565b611836565b6040516104789190612d39565b60405180910390f35b34801561048d57600080fd5b506104a860048036038101906104a39190612dbf565b6118c0565b6040516104b6929190613001565b60405180910390f35b3480156104cb57600080fd5b506104e660048036038101906104e19190612697565b61195e565b6040516104f39190612b0b565b60405180910390f35b34801561050857600080fd5b50610523600480360381019061051e919061297f565b6119e7565b6040516105309190612ada565b60405180910390f35b34801561054557600080fd5b50610560600480360381019061055b919061297f565b611a76565b60405161056d9190612ada565b60405180910390f35b34801561058257600080fd5b5061059d60048036038101906105989190613038565b611b02565b6040516105aa9190612ada565b60405180910390f35b3480156105bf57600080fd5b506105da60048036038101906105d591906130bb565b611d8d565b6040516105e79190612ada565b60405180910390f35b3480156105fc57600080fd5b5061061760048036038101906106129190612483565b611ee2565b6040516106249190613208565b60405180910390f35b34801561063957600080fd5b50610654600480360381019061064f919061322a565b611f6c565b6040516106619190612b0b565b60405180910390f35b34801561067657600080fd5b50610691600480360381019061068c9190612483565b612084565b60405161069e91906132b4565b60405180910390f35b6106af61210e565b005b3480156106bd57600080fd5b506106d860048036038101906106d39190612697565b612110565b6040516106e59190612d39565b60405180910390f35b3480156106fa57600080fd5b5061071560048036038101906107109190612697565b61219a565b6040516107229190612ada565b60405180910390f35b34801561073757600080fd5b50610752600480360381019061074d9190612483565b612226565b6040516107609291906133dc565b60405180910390f35b811561089a5760008081819054906101000a900460070b8092919061078d90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146108995760008473ffffffffffffffffffffffffffffffffffffffff16600f604051610811906134a3565b60006040518083038185875af1925050503d806000811461084e576040519150601f19603f3d011682016040523d82523d6000602084013e610853565b606091505b5050905080610897576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088e9061352a565b60405180910390fd5b505b5b600061080173ffffffffffffffffffffffffffffffffffffffff16632efe8a5f86866040518363ffffffff1660e01b81526004016108d99291906135b8565b6020604051808303816000875af11580156108f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091c91906135f6565b90508061095e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061366f565b60405180910390fd5b8115610a8f5760008081819054906101000a900460070b8092919061098290613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610a8e5760008573ffffffffffffffffffffffffffffffffffffffff16600f604051610a06906134a3565b60006040518083038185875af1925050503d8060008114610a43576040519150601f19603f3d011682016040523d82523d6000602084013e610a48565b606091505b5050905080610a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a839061352a565b60405180910390fd5b505b5b5050505050565b606060008061080173ffffffffffffffffffffffffffffffffffffffff1684604051602401610ac5919061369e565b6040516020818303038152906040527f5431f450000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610b4f91906136ea565b600060405180830381855afa9150503d8060008114610b8a576040519150601f19603f3d011682016040523d82523d6000602084013e610b8f565b606091505b509150915081610bd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcb9061374d565b60405180910390fd5b8092505050919050565b610be66122b3565b61080173ffffffffffffffffffffffffffffffffffffffff166354212a89836040518263ffffffff1660e01b8152600401610c2191906132b4565b600060405180830381865afa158015610c3e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610c679190613a46565b9050919050565b3073ffffffffffffffffffffffffffffffffffffffff1663ad5c4cdd85846040518363ffffffff1660e01b8152600401610ca9929190613a8f565b6000604051808303816000875af1925050508015610cea57506040513d6000823e3d601f19601f82011682018060405250810190610ce79190613c0c565b60015b15610cf157505b8015610dee5760008081819054906101000a900460070b80929190610d1590613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008373ffffffffffffffffffffffffffffffffffffffff16600f604051610d66906134a3565b60006040518083038185875af1925050503d8060008114610da3576040519150601f19603f3d011682016040523d82523d6000602084013e610da8565b606091505b5050905080610dec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de39061352a565b60405180910390fd5b505b50505050565b600061080173ffffffffffffffffffffffffffffffffffffffff168383604051602401610e22929190613c55565b6040516020818303038152906040527f5a9d9a96000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610eac91906136ea565b600060405180830381855af49150503d8060008114610ee7576040519150601f19603f3d011682016040523d82523d6000602084013e610eec565b606091505b5050905080610f30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2790613cf7565b60405180910390fd5b505050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6130846040518363ffffffff1660e01b8152600401610f74929190613c55565b6000604051808303816000875af1158015610f93573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610fbc9190613c0c565b9050919050565b600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9684846040518363ffffffff1660e01b8152600401611002929190613c55565b6020604051808303816000875af1158015611021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104591906135f6565b905092915050565b606082156111805760008081819054906101000a900460070b8092919061107390613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461117f5760008473ffffffffffffffffffffffffffffffffffffffff16600f6040516110f7906134a3565b60006040518083038185875af1925050503d8060008114611134576040519150601f19603f3d011682016040523d82523d6000602084013e611139565b606091505b505090508061117d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111749061352a565b60405180910390fd5b505b5b61080173ffffffffffffffffffffffffffffffffffffffff16633ce4e3be866040518263ffffffff1660e01b81526004016111bb91906132b4565b6000604051808303816000875af11580156111da573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112039190613c0c565b905081156113365760008081819054906101000a900460070b8092919061122990613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146113355760008473ffffffffffffffffffffffffffffffffffffffff16600f6040516112ad906134a3565b60006040518083038185875af1925050503d80600081146112ea576040519150601f19603f3d011682016040523d82523d6000602084013e6112ef565b606091505b5050905080611333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132a9061352a565b60405180910390fd5b505b5b949350505050565b60008054906101000a900460070b81565b811561144c5760008081819054906101000a900460070b8092919061137390613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008473ffffffffffffffffffffffffffffffffffffffff16600f6040516113c4906134a3565b60006040518083038185875af1925050503d8060008114611401576040519150601f19603f3d011682016040523d82523d6000602084013e611406565b606091505b505090508061144a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114419061352a565b60405180910390fd5b505b600061080173ffffffffffffffffffffffffffffffffffffffff1663ed41d0b686866040518363ffffffff1660e01b815260040161148b929190613d26565b6020604051808303816000875af11580156114aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce91906135f6565b9050806114da57600080fd5b81156115d75760008081819054906101000a900460070b809291906114fe90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f60405161154f906134a3565b60006040518083038185875af1925050503d806000811461158c576040519150601f19603f3d011682016040523d82523d6000602084013e611591565b606091505b50509050806115d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115cc9061352a565b60405180910390fd5b505b5050505050565b600061080173ffffffffffffffffffffffffffffffffffffffff16632efe8a5f84846040518363ffffffff1660e01b815260040161161d929190613d4f565b6020604051808303816000875af115801561163c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166091906135f6565b905092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff16639ad563b484846040518363ffffffff1660e01b81526004016116a7929190613c55565b600060405180830381865afa1580156116c4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906116ed9190613d78565b905092915050565b600061080173ffffffffffffffffffffffffffffffffffffffff168383604051602401611723929190613c55565b6040516020818303038152906040527f5a9d9a96000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516117ad91906136ea565b600060405180830381855afa9150503d80600081146117e8576040519150601f19603f3d011682016040523d82523d6000602084013e6117ed565b606091505b5050905080611831576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118289061374d565b60405180910390fd5b505050565b606061080173ffffffffffffffffffffffffffffffffffffffff16633dd40f78836040518263ffffffff1660e01b815260040161187391906132b4565b600060405180830381865afa158015611890573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906118b99190613d78565b9050919050565b60606118ca6122d4565b61080173ffffffffffffffffffffffffffffffffffffffff16638f2473ce878787876040518563ffffffff1660e01b815260040161190b9493929190613f4c565b600060405180830381865afa158015611928573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906119519190614224565b9150915094509492505050565b600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9630846040518363ffffffff1660e01b815260040161199d929190613c55565b6020604051808303816000875af11580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e091906135f6565b9050919050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6184846040518363ffffffff1660e01b8152600401611a26929190613c55565b6000604051808303816000875af1158015611a45573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611a6e9190613c0c565b905092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6184846040518363ffffffff1660e01b8152600401611ab5929190613c55565b6000604051808303816000875af1158015611ad4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611afd9190613c0c565b600080fd5b60608215611c015760008081819054906101000a900460070b80929190611b2890613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f604051611b79906134a3565b60006040518083038185875af1925050503d8060008114611bb6576040519150601f19603f3d011682016040523d82523d6000602084013e611bbb565b606091505b5050905080611bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf69061352a565b60405180910390fd5b505b61080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6186866040518363ffffffff1660e01b8152600401611c3e929190613a8f565b6000604051808303816000875af1158015611c5d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611c869190613c0c565b90508115611d855760008081819054906101000a900460070b80929190611cac90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f604051611cfd906134a3565b60006040518083038185875af1925050503d8060008114611d3a576040519150601f19603f3d011682016040523d82523d6000602084013e611d3f565b606091505b5050905080611d83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7a9061352a565b60405180910390fd5b505b949350505050565b6060600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9633876040518363ffffffff1660e01b8152600401611dce929190613c55565b6020604051808303816000875af1158015611ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1191906135f6565b905080611e53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4a906142e8565b60405180910390fd5b61080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6185856040518363ffffffff1660e01b8152600401611e90929190613c55565b6000604051808303816000875af1158015611eaf573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ed89190613c0c565b9150509392505050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663a66cb605836040518263ffffffff1660e01b8152600401611f1f919061369e565b600060405180830381865afa158015611f3c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611f6591906143e9565b9050919050565b600060016000808282829054906101000a900460070b611f8c9190614432565b92506101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff16021790555061080173ffffffffffffffffffffffffffffffffffffffff1663ed41d0b684846040518363ffffffff1660e01b8152600401611ff2929190614492565b6020604051808303816000875af1158015612011573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203591906135f6565b905060016000808282829054906101000a900460070b61205591906144bb565b92506101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff16021790555092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff16635431f450836040518263ffffffff1660e01b81526004016120c1919061369e565b600060405180830381865afa1580156120de573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612107919061451b565b9050919050565b565b606061080173ffffffffffffffffffffffffffffffffffffffff166385b2d2da836040518263ffffffff1660e01b815260040161214d91906132b4565b600060405180830381865afa15801561216a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121939190613d78565b9050919050565b606061080173ffffffffffffffffffffffffffffffffffffffff16633ce4e3be836040518263ffffffff1660e01b81526004016121d791906132b4565b6000604051808303816000875af11580156121f6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061221f9190613c0c565b9050919050565b60608061080173ffffffffffffffffffffffffffffffffffffffff166354be1a28846040518263ffffffff1660e01b8152600401612264919061369e565b600060405180830381865afa158015612281573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122aa91906146cd565b91509150915091565b60405180606001604052806060815260200160608152602001606081525090565b604051806040016040528060608152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006123378261230c565b9050919050565b6123478161232c565b811461235257600080fd5b50565b6000813590506123648161233e565b92915050565b600063ffffffff82169050919050565b6123838161236a565b811461238e57600080fd5b50565b6000813590506123a08161237a565b92915050565b60008115159050919050565b6123bb816123a6565b81146123c657600080fd5b50565b6000813590506123d8816123b2565b92915050565b600080600080608085870312156123f8576123f7612302565b5b600061240687828801612355565b945050602061241787828801612391565b9350506040612428878288016123c9565b9250506060612439878288016123c9565b91505092959194509250565b60006124508261230c565b9050919050565b61246081612445565b811461246b57600080fd5b50565b60008135905061247d81612457565b92915050565b60006020828403121561249957612498612302565b5b60006124a78482850161246e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156124ea5780820151818401526020810190506124cf565b60008484015250505050565b6000601f19601f8301169050919050565b6000612512826124b0565b61251c81856124bb565b935061252c8185602086016124cc565b612535816124f6565b840191505092915050565b6000602082019050818103600083015261255a8184612507565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125a4826124f6565b810181811067ffffffffffffffff821117156125c3576125c261256c565b5b80604052505050565b60006125d66122f8565b90506125e2828261259b565b919050565b600067ffffffffffffffff8211156126025761260161256c565b5b61260b826124f6565b9050602081019050919050565b82818337600083830152505050565b600061263a612635846125e7565b6125cc565b90508281526020810184848401111561265657612655612567565b5b612661848285612618565b509392505050565b600082601f83011261267e5761267d612562565b5b813561268e848260208601612627565b91505092915050565b6000602082840312156126ad576126ac612302565b5b600082013567ffffffffffffffff8111156126cb576126ca612307565b5b6126d784828501612669565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000612707826126e0565b61271181856126eb565b93506127218185602086016124cc565b61272a816124f6565b840191505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b61277481612761565b82525050565b600060ff82169050919050565b6127908161277a565b82525050565b600060608301600083015184820360008601526127b382826126fc565b91505060208301516127c8602086018261276b565b5060408301516127db6040860182612787565b508091505092915050565b60006127f28383612796565b905092915050565b6000602082019050919050565b600061281282612735565b61281c8185612740565b93508360208202850161282e85612751565b8060005b8581101561286a578484038952815161284b85826127e6565b9450612856836127fa565b925060208a01995050600181019050612832565b50829750879550505050505092915050565b6000606083016000830151848203600086015261289982826126fc565b915050602083015184820360208601526128b38282612807565b915050604083015184820360408601526128cd8282612807565b9150508091505092915050565b600060208201905081810360008301526128f4818461287c565b905092915050565b6000806000806080858703121561291657612915612302565b5b600061292487828801612355565b945050602061293587828801612355565b935050604085013567ffffffffffffffff81111561295657612955612307565b5b61296287828801612669565b9250506060612973878288016123c9565b91505092959194509250565b6000806040838503121561299657612995612302565b5b60006129a48582860161246e565b925050602083013567ffffffffffffffff8111156129c5576129c4612307565b5b6129d185828601612669565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006040830160008301518482036000860152612a2482826126fc565b9150506020830151612a39602086018261276b565b508091505092915050565b6000612a508383612a07565b905092915050565b6000602082019050919050565b6000612a70826129db565b612a7a81856129e6565b935083602082028501612a8c856129f7565b8060005b85811015612ac85784840389528151612aa98582612a44565b9450612ab483612a58565b925060208a01995050600181019050612a90565b50829750879550505050505092915050565b60006020820190508181036000830152612af48184612a65565b905092915050565b612b05816123a6565b82525050565b6000602082019050612b206000830184612afc565b92915050565b60008060008060808587031215612b4057612b3f612302565b5b600085013567ffffffffffffffff811115612b5e57612b5d612307565b5b612b6a87828801612669565b9450506020612b7b87828801612355565b9350506040612b8c878288016123c9565b9250506060612b9d878288016123c9565b91505092959194509250565b60008160070b9050919050565b612bbf81612ba9565b82525050565b6000602082019050612bda6000830184612bb6565b92915050565b612be981612761565b8114612bf457600080fd5b50565b600081359050612c0681612be0565b92915050565b60008060008060808587031215612c2657612c25612302565b5b6000612c3487828801612355565b9450506020612c4587828801612bf7565b9350506040612c56878288016123c9565b9250506060612c67878288016123c9565b91505092959194509250565b60008060408385031215612c8a57612c89612302565b5b6000612c988582860161246e565b9250506020612ca985828601612391565b9150509250929050565b600082825260208201905092915050565b6000612ccf82612735565b612cd98185612cb3565b935083602082028501612ceb85612751565b8060005b85811015612d275784840389528151612d0885826127e6565b9450612d13836127fa565b925060208a01995050600181019050612cef565b50829750879550505050505092915050565b60006020820190508181036000830152612d538184612cc4565b905092915050565b600067ffffffffffffffff82169050919050565b612d7881612d5b565b8114612d8357600080fd5b50565b600081359050612d9581612d6f565b92915050565b600080fd5b600060a08284031215612db657612db5612d9b565b5b81905092915050565b60008060008060808587031215612dd957612dd8612302565b5b600085013567ffffffffffffffff811115612df757612df6612307565b5b612e0387828801612669565b9450506020612e1487828801612d86565b9350506040612e2587828801612d86565b925050606085013567ffffffffffffffff811115612e4657612e45612307565b5b612e5287828801612da0565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612e9381612d5b565b82525050565b604082016000820151612eaf600085018261276b565b506020820151612ec26020850182612787565b50505050565b606082016000820151612ede6000850182612e8a565b506020820151612ef16020850182612e99565b50505050565b6000612f038383612ec8565b60608301905092915050565b6000602082019050919050565b6000612f2782612e5e565b612f318185612e69565b9350612f3c83612e7a565b8060005b83811015612f6d578151612f548882612ef7565b9750612f5f83612f0f565b925050600181019050612f40565b5085935050505092915050565b600082825260208201905092915050565b6000612f96826124b0565b612fa08185612f7a565b9350612fb08185602086016124cc565b612fb9816124f6565b840191505092915050565b60006040830160008301518482036000860152612fe18282612f8b565b9150506020830151612ff66020860182612e8a565b508091505092915050565b6000604082019050818103600083015261301b8185612f1c565b9050818103602083015261302f8184612fc4565b90509392505050565b6000806000806080858703121561305257613051612302565b5b600061306087828801612355565b945050602085013567ffffffffffffffff81111561308157613080612307565b5b61308d87828801612669565b935050604061309e878288016123c9565b92505060606130af878288016123c9565b91505092959194509250565b6000806000606084860312156130d4576130d3612302565b5b600084013567ffffffffffffffff8111156130f2576130f1612307565b5b6130fe86828701612669565b935050602061310f8682870161246e565b925050604084013567ffffffffffffffff8111156131305761312f612307565b5b61313c86828701612669565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061317e83836126fc565b905092915050565b6000602082019050919050565b600061319e82613146565b6131a88185613151565b9350836020820285016131ba85613162565b8060005b858110156131f657848403895281516131d78582613172565b94506131e283613186565b925060208a019950506001810190506131be565b50829750879550505050505092915050565b600060208201905081810360008301526132228184613193565b905092915050565b6000806040838503121561324157613240612302565b5b600061324f8582860161246e565b925050602061326085828601612bf7565b9150509250929050565b600082825260208201905092915050565b6000613286826126e0565b613290818561326a565b93506132a08185602086016124cc565b6132a9816124f6565b840191505092915050565b600060208201905081810360008301526132ce818461327b565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000604083016000830151848203600086015261331f82826126fc565b915050602083015184820360208601526133398282612807565b9150508091505092915050565b60006133528383613302565b905092915050565b6000602082019050919050565b6000613372826132d6565b61337c81856132e1565b93508360208202850161338e856132f2565b8060005b858110156133ca57848403895281516133ab8582613346565b94506133b68361335a565b925060208a01995050600181019050613392565b50829750879550505050505092915050565b600060408201905081810360008301526133f68185613367565b9050818103602083015261340a8184612cc4565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061344d82612ba9565b9150677fffffffffffffff820361346757613466613413565b5b600182019050919050565b600081905092915050565b50565b600061348d600083613472565b91506134988261347d565b600082019050919050565b60006134ae82613480565b9150819050919050565b7f4661696c656420746f2073656e6420457468657220746f2064656c656761746f60008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061351460218361326a565b915061351f826134b8565b604082019050919050565b6000602082019050818103600083015261354381613507565b9050919050565b6000819050919050565b600061356f61356a6135658461230c565b61354a565b61230c565b9050919050565b600061358182613554565b9050919050565b600061359382613576565b9050919050565b6135a381613588565b82525050565b6135b28161236a565b82525050565b60006040820190506135cd600083018561359a565b6135da60208301846135a9565b9392505050565b6000815190506135f0816123b2565b92915050565b60006020828403121561360c5761360b612302565b5b600061361a848285016135e1565b91505092915050565b7f6661696c656420746f20636c61696d2072657761726473000000000000000000600082015250565b600061365960178361326a565b915061366482613623565b602082019050919050565b600060208201905081810360008301526136888161364c565b9050919050565b61369881612445565b82525050565b60006020820190506136b3600083018461368f565b92915050565b60006136c4826124b0565b6136ce8185613472565b93506136de8185602086016124cc565b80840191505092915050565b60006136f682846136b9565b915081905092915050565b7f6661696c65642073746174696343616c6c20746f20707265636f6d70696c6500600082015250565b6000613737601f8361326a565b915061374282613701565b602082019050919050565b600060208201905081810360008301526137668161372a565b9050919050565b600080fd5b600080fd5b600061378a613785846125e7565b6125cc565b9050828152602081018484840111156137a6576137a5612567565b5b6137b18482856124cc565b509392505050565b600082601f8301126137ce576137cd612562565b5b81516137de848260208601613777565b91505092915050565b600067ffffffffffffffff8211156138025761380161256c565b5b602082029050602081019050919050565b600080fd5b60008151905061382781612be0565b92915050565b6138368161277a565b811461384157600080fd5b50565b6000815190506138538161382d565b92915050565b60006060828403121561386f5761386e61376d565b5b61387960606125cc565b9050600082015167ffffffffffffffff81111561389957613898613772565b5b6138a5848285016137b9565b60008301525060206138b984828501613818565b60208301525060406138cd84828501613844565b60408301525092915050565b60006138ec6138e7846137e7565b6125cc565b9050808382526020820190506020840283018581111561390f5761390e613813565b5b835b8181101561395657805167ffffffffffffffff81111561393457613933612562565b5b8086016139418982613859565b85526020850194505050602081019050613911565b5050509392505050565b600082601f83011261397557613974612562565b5b81516139858482602086016138d9565b91505092915050565b6000606082840312156139a4576139a361376d565b5b6139ae60606125cc565b9050600082015167ffffffffffffffff8111156139ce576139cd613772565b5b6139da848285016137b9565b600083015250602082015167ffffffffffffffff8111156139fe576139fd613772565b5b613a0a84828501613960565b602083015250604082015167ffffffffffffffff811115613a2e57613a2d613772565b5b613a3a84828501613960565b60408301525092915050565b600060208284031215613a5c57613a5b612302565b5b600082015167ffffffffffffffff811115613a7a57613a79612307565b5b613a868482850161398e565b91505092915050565b6000604082019050613aa4600083018561359a565b8181036020830152613ab6818461327b565b90509392505050565b600067ffffffffffffffff821115613ada57613ad961256c565b5b602082029050602081019050919050565b600060408284031215613b0157613b0061376d565b5b613b0b60406125cc565b9050600082015167ffffffffffffffff811115613b2b57613b2a613772565b5b613b37848285016137b9565b6000830152506020613b4b84828501613818565b60208301525092915050565b6000613b6a613b6584613abf565b6125cc565b90508083825260208201905060208402830185811115613b8d57613b8c613813565b5b835b81811015613bd457805167ffffffffffffffff811115613bb257613bb1612562565b5b808601613bbf8982613aeb565b85526020850194505050602081019050613b8f565b5050509392505050565b600082601f830112613bf357613bf2612562565b5b8151613c03848260208601613b57565b91505092915050565b600060208284031215613c2257613c21612302565b5b600082015167ffffffffffffffff811115613c4057613c3f612307565b5b613c4c84828501613bde565b91505092915050565b6000604082019050613c6a600083018561368f565b8181036020830152613c7c818461327b565b90509392505050565b7f6661696c65642064656c656761746543616c6c20746f20707265636f6d70696c60008201527f6500000000000000000000000000000000000000000000000000000000000000602082015250565b6000613ce160218361326a565b9150613cec82613c85565b604082019050919050565b60006020820190508181036000830152613d1081613cd4565b9050919050565b613d2081612761565b82525050565b6000604082019050613d3b600083018561359a565b613d486020830184613d17565b9392505050565b6000604082019050613d64600083018561368f565b613d7160208301846135a9565b9392505050565b600060208284031215613d8e57613d8d612302565b5b600082015167ffffffffffffffff811115613dac57613dab612307565b5b613db884828501613960565b91505092915050565b613dca81612d5b565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112613dfc57613dfb613dda565b5b83810192508235915060208301925067ffffffffffffffff821115613e2457613e23613dd0565b5b600182023603831315613e3a57613e39613dd5565b5b509250929050565b6000613e4e8385612f7a565b9350613e5b838584612618565b613e64836124f6565b840190509392505050565b6000613e7e6020840184612d86565b905092915050565b6000613e9560208401846123c9565b905092915050565b613ea6816123a6565b82525050565b600060a08301613ebf6000840184613ddf565b8583036000870152613ed2838284613e42565b92505050613ee36020840184613e6f565b613ef06020860182612e8a565b50613efe6040840184613e6f565b613f0b6040860182612e8a565b50613f196060840184613e86565b613f266060860182613e9d565b50613f346080840184613e86565b613f416080860182613e9d565b508091505092915050565b60006080820190508181036000830152613f66818761327b565b9050613f756020830186613dc1565b613f826040830185613dc1565b8181036060830152613f948184613eac565b905095945050505050565b600067ffffffffffffffff821115613fba57613fb961256c565b5b602082029050602081019050919050565b600081519050613fda81612d6f565b92915050565b600060408284031215613ff657613ff561376d565b5b61400060406125cc565b9050600061401084828501613818565b600083015250602061402484828501613844565b60208301525092915050565b6000606082840312156140465761404561376d565b5b61405060406125cc565b9050600061406084828501613fcb565b600083015250602061407484828501613fe0565b60208301525092915050565b600061409361408e84613f9f565b6125cc565b905080838252602082019050606084028301858111156140b6576140b5613813565b5b835b818110156140df57806140cb8882614030565b8452602084019350506060810190506140b8565b5050509392505050565b600082601f8301126140fe576140fd612562565b5b815161410e848260208601614080565b91505092915050565b600067ffffffffffffffff8211156141325761413161256c565b5b61413b826124f6565b9050602081019050919050565b600061415b61415684614117565b6125cc565b90508281526020810184848401111561417757614176612567565b5b6141828482856124cc565b509392505050565b600082601f83011261419f5761419e612562565b5b81516141af848260208601614148565b91505092915050565b6000604082840312156141ce576141cd61376d565b5b6141d860406125cc565b9050600082015167ffffffffffffffff8111156141f8576141f7613772565b5b6142048482850161418a565b600083015250602061421884828501613fcb565b60208301525092915050565b6000806040838503121561423b5761423a612302565b5b600083015167ffffffffffffffff81111561425957614258612307565b5b614265858286016140e9565b925050602083015167ffffffffffffffff81111561428657614285612307565b5b614292858286016141b8565b9150509250929050565b7f6661696c656420746f2073657420776974686472617720616464726573730000600082015250565b60006142d2601e8361326a565b91506142dd8261429c565b602082019050919050565b60006020820190508181036000830152614301816142c5565b9050919050565b600067ffffffffffffffff8211156143235761432261256c565b5b602082029050602081019050919050565b600061434761434284614308565b6125cc565b9050808382526020820190506020840283018581111561436a57614369613813565b5b835b818110156143b157805167ffffffffffffffff81111561438f5761438e612562565b5b80860161439c89826137b9565b8552602085019450505060208101905061436c565b5050509392505050565b600082601f8301126143d0576143cf612562565b5b81516143e0848260208601614334565b91505092915050565b6000602082840312156143ff576143fe612302565b5b600082015167ffffffffffffffff81111561441d5761441c612307565b5b614429848285016143bb565b91505092915050565b600061443d82612ba9565b915061444883612ba9565b925082820190507fffffffffffffffffffffffffffffffffffffffffffffffff80000000000000008112677fffffffffffffff8213171561448c5761448b613413565b5b92915050565b60006040820190506144a7600083018561368f565b6144b46020830184613d17565b9392505050565b60006144c682612ba9565b91506144d183612ba9565b92508282039050677fffffffffffffff81137fffffffffffffffffffffffffffffffffffffffffffffffff80000000000000008212171561451557614514613413565b5b92915050565b60006020828403121561453157614530612302565b5b600082015167ffffffffffffffff81111561454f5761454e612307565b5b61455b848285016137b9565b91505092915050565b600067ffffffffffffffff82111561457f5761457e61256c565b5b602082029050602081019050919050565b6000604082840312156145a6576145a561376d565b5b6145b060406125cc565b9050600082015167ffffffffffffffff8111156145d0576145cf613772565b5b6145dc848285016137b9565b600083015250602082015167ffffffffffffffff811115614600576145ff613772565b5b61460c84828501613960565b60208301525092915050565b600061462b61462684614564565b6125cc565b9050808382526020820190506020840283018581111561464e5761464d613813565b5b835b8181101561469557805167ffffffffffffffff81111561467357614672612562565b5b8086016146808982614590565b85526020850194505050602081019050614650565b5050509392505050565b600082601f8301126146b4576146b3612562565b5b81516146c4848260208601614618565b91505092915050565b600080604083850312156146e4576146e3612302565b5b600083015167ffffffffffffffff81111561470257614701612307565b5b61470e8582860161469f565b925050602083015167ffffffffffffffff81111561472f5761472e612307565b5b61473b85828601613960565b915050925092905056fea2646970667358221220a8fdbc3760bca6bed7c0d0a8bfa4c3e75e199774f0a60a0a34530a58ee2456ed64736f6c63430008130033",
+  "deployedBytecode": "0x60806040526004361061019c5760003560e01c80637c9db0bb116100ec578063b6a216ae1161008a578063d0e30db011610064578063d0e30db0146106a7578063d3f831be146106b1578063e0421e39146106ee578063e236c7a61461072b5761019c565b8063b6a216ae146105f0578063c7804bb51461062d578063cb85aa0a1461066a5761019c565b806398194593116100c657806398194593146104fc578063ad5c4cdd14610539578063adb2378514610576578063b2d17883146105b35761019c565b80637c9db0bb1461044457806388b2d58114610481578063963516e4146104bf5761019c565b806346e16d34116101595780636cc9ac8a116101335780636cc9ac8a146103785780636f669da4146103a157806378a5dfd1146103de578063796b96d21461041b5761019c565b806346e16d34146102d3578063613d4de81461031057806361bc221a1461034d5761019c565b80630183e4b4146101a157806301b68000146101ca5780630c05e9e4146102075780631b05020714610244578063296c60aa1461026d5780632d0ee16a14610296575b600080fd5b3480156101ad57600080fd5b506101c860048036038101906101c391906123de565b610769565b005b3480156101d657600080fd5b506101f160048036038101906101ec9190612483565b610a96565b6040516101fe9190612540565b60405180910390f35b34801561021357600080fd5b5061022e60048036038101906102299190612697565b610bde565b60405161023b91906128da565b60405180910390f35b34801561025057600080fd5b5061026b600480360381019061026691906128fc565b610c6e565b005b34801561027957600080fd5b50610294600480360381019061028f919061297f565b610df4565b005b3480156102a257600080fd5b506102bd60048036038101906102b89190612697565b610f35565b6040516102ca9190612ada565b60405180910390f35b3480156102df57600080fd5b506102fa60048036038101906102f5919061297f565b610fc3565b6040516103079190612b0b565b60405180910390f35b34801561031c57600080fd5b5061033760048036038101906103329190612b26565b61104d565b6040516103449190612ada565b60405180910390f35b34801561035957600080fd5b5061036261133e565b60405161036f9190612bc5565b60405180910390f35b34801561038457600080fd5b5061039f600480360381019061039a9190612c0c565b61134f565b005b3480156103ad57600080fd5b506103c860048036038101906103c39190612c73565b6115de565b6040516103d59190612b0b565b60405180910390f35b3480156103ea57600080fd5b506104056004803603810190610400919061297f565b611668565b6040516104129190612d39565b60405180910390f35b34801561042757600080fd5b50610442600480360381019061043d919061297f565b6116f5565b005b34801561045057600080fd5b5061046b60048036038101906104669190612697565b611836565b6040516104789190612d39565b60405180910390f35b34801561048d57600080fd5b506104a860048036038101906104a39190612dbf565b6118c0565b6040516104b6929190613001565b60405180910390f35b3480156104cb57600080fd5b506104e660048036038101906104e19190612697565b61195e565b6040516104f39190612b0b565b60405180910390f35b34801561050857600080fd5b50610523600480360381019061051e919061297f565b6119e7565b6040516105309190612ada565b60405180910390f35b34801561054557600080fd5b50610560600480360381019061055b919061297f565b611a76565b60405161056d9190612ada565b60405180910390f35b34801561058257600080fd5b5061059d60048036038101906105989190613038565b611b02565b6040516105aa9190612ada565b60405180910390f35b3480156105bf57600080fd5b506105da60048036038101906105d591906130bb565b611d8d565b6040516105e79190612ada565b60405180910390f35b3480156105fc57600080fd5b5061061760048036038101906106129190612483565b611ee2565b6040516106249190613208565b60405180910390f35b34801561063957600080fd5b50610654600480360381019061064f919061322a565b611f6c565b6040516106619190612b0b565b60405180910390f35b34801561067657600080fd5b50610691600480360381019061068c9190612483565b612084565b60405161069e91906132b4565b60405180910390f35b6106af61210e565b005b3480156106bd57600080fd5b506106d860048036038101906106d39190612697565b612110565b6040516106e59190612d39565b60405180910390f35b3480156106fa57600080fd5b5061071560048036038101906107109190612697565b61219a565b6040516107229190612ada565b60405180910390f35b34801561073757600080fd5b50610752600480360381019061074d9190612483565b612226565b6040516107609291906133dc565b60405180910390f35b811561089a5760008081819054906101000a900460070b8092919061078d90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146108995760008473ffffffffffffffffffffffffffffffffffffffff16600f604051610811906134a3565b60006040518083038185875af1925050503d806000811461084e576040519150601f19603f3d011682016040523d82523d6000602084013e610853565b606091505b5050905080610897576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088e9061352a565b60405180910390fd5b505b5b600061080173ffffffffffffffffffffffffffffffffffffffff16632efe8a5f86866040518363ffffffff1660e01b81526004016108d99291906135b8565b6020604051808303816000875af11580156108f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091c91906135f6565b90508061095e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061366f565b60405180910390fd5b8115610a8f5760008081819054906101000a900460070b8092919061098290613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610a8e5760008573ffffffffffffffffffffffffffffffffffffffff16600f604051610a06906134a3565b60006040518083038185875af1925050503d8060008114610a43576040519150601f19603f3d011682016040523d82523d6000602084013e610a48565b606091505b5050905080610a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a839061352a565b60405180910390fd5b505b5b5050505050565b606060008061080173ffffffffffffffffffffffffffffffffffffffff1684604051602401610ac5919061369e565b6040516020818303038152906040527f5431f450000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610b4f91906136ea565b600060405180830381855afa9150503d8060008114610b8a576040519150601f19603f3d011682016040523d82523d6000602084013e610b8f565b606091505b509150915081610bd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcb9061374d565b60405180910390fd5b8092505050919050565b610be66122b3565b61080173ffffffffffffffffffffffffffffffffffffffff166354212a89836040518263ffffffff1660e01b8152600401610c2191906132b4565b600060405180830381865afa158015610c3e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610c679190613a46565b9050919050565b3073ffffffffffffffffffffffffffffffffffffffff1663ad5c4cdd85846040518363ffffffff1660e01b8152600401610ca9929190613a8f565b6000604051808303816000875af1925050508015610cea57506040513d6000823e3d601f19601f82011682018060405250810190610ce79190613c0c565b60015b15610cf157505b8015610dee5760008081819054906101000a900460070b80929190610d1590613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008373ffffffffffffffffffffffffffffffffffffffff16600f604051610d66906134a3565b60006040518083038185875af1925050503d8060008114610da3576040519150601f19603f3d011682016040523d82523d6000602084013e610da8565b606091505b5050905080610dec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de39061352a565b60405180910390fd5b505b50505050565b600061080173ffffffffffffffffffffffffffffffffffffffff168383604051602401610e22929190613c55565b6040516020818303038152906040527f5a9d9a96000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610eac91906136ea565b600060405180830381855af49150503d8060008114610ee7576040519150601f19603f3d011682016040523d82523d6000602084013e610eec565b606091505b5050905080610f30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2790613cf7565b60405180910390fd5b505050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6130846040518363ffffffff1660e01b8152600401610f74929190613c55565b6000604051808303816000875af1158015610f93573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610fbc9190613c0c565b9050919050565b600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9684846040518363ffffffff1660e01b8152600401611002929190613c55565b6020604051808303816000875af1158015611021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104591906135f6565b905092915050565b606082156111805760008081819054906101000a900460070b8092919061107390613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461117f5760008473ffffffffffffffffffffffffffffffffffffffff16600f6040516110f7906134a3565b60006040518083038185875af1925050503d8060008114611134576040519150601f19603f3d011682016040523d82523d6000602084013e611139565b606091505b505090508061117d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111749061352a565b60405180910390fd5b505b5b61080173ffffffffffffffffffffffffffffffffffffffff16633ce4e3be866040518263ffffffff1660e01b81526004016111bb91906132b4565b6000604051808303816000875af11580156111da573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112039190613c0c565b905081156113365760008081819054906101000a900460070b8092919061122990613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff160217905550503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146113355760008473ffffffffffffffffffffffffffffffffffffffff16600f6040516112ad906134a3565b60006040518083038185875af1925050503d80600081146112ea576040519150601f19603f3d011682016040523d82523d6000602084013e6112ef565b606091505b5050905080611333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132a9061352a565b60405180910390fd5b505b5b949350505050565b60008054906101000a900460070b81565b811561144c5760008081819054906101000a900460070b8092919061137390613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008473ffffffffffffffffffffffffffffffffffffffff16600f6040516113c4906134a3565b60006040518083038185875af1925050503d8060008114611401576040519150601f19603f3d011682016040523d82523d6000602084013e611406565b606091505b505090508061144a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114419061352a565b60405180910390fd5b505b600061080173ffffffffffffffffffffffffffffffffffffffff1663ed41d0b686866040518363ffffffff1660e01b815260040161148b929190613d26565b6020604051808303816000875af11580156114aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce91906135f6565b9050806114da57600080fd5b81156115d75760008081819054906101000a900460070b809291906114fe90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f60405161154f906134a3565b60006040518083038185875af1925050503d806000811461158c576040519150601f19603f3d011682016040523d82523d6000602084013e611591565b606091505b50509050806115d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115cc9061352a565b60405180910390fd5b505b5050505050565b600061080173ffffffffffffffffffffffffffffffffffffffff16632efe8a5f84846040518363ffffffff1660e01b815260040161161d929190613d4f565b6020604051808303816000875af115801561163c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166091906135f6565b905092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff16639ad563b484846040518363ffffffff1660e01b81526004016116a7929190613c55565b600060405180830381865afa1580156116c4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906116ed9190613d78565b905092915050565b600061080173ffffffffffffffffffffffffffffffffffffffff168383604051602401611723929190613c55565b6040516020818303038152906040527f5a9d9a96000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516117ad91906136ea565b600060405180830381855afa9150503d80600081146117e8576040519150601f19603f3d011682016040523d82523d6000602084013e6117ed565b606091505b5050905080611831576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118289061374d565b60405180910390fd5b505050565b606061080173ffffffffffffffffffffffffffffffffffffffff16633dd40f78836040518263ffffffff1660e01b815260040161187391906132b4565b600060405180830381865afa158015611890573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906118b99190613d78565b9050919050565b60606118ca6122d4565b61080173ffffffffffffffffffffffffffffffffffffffff16638f2473ce878787876040518563ffffffff1660e01b815260040161190b9493929190613f4c565b600060405180830381865afa158015611928573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906119519190614224565b9150915094509492505050565b600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9630846040518363ffffffff1660e01b815260040161199d929190613c55565b6020604051808303816000875af11580156119bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e091906135f6565b9050919050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6184846040518363ffffffff1660e01b8152600401611a26929190613c55565b6000604051808303816000875af1158015611a45573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611a6e9190613c0c565b905092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6184846040518363ffffffff1660e01b8152600401611ab5929190613c55565b6000604051808303816000875af1158015611ad4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611afd9190613c0c565b600080fd5b60608215611c015760008081819054906101000a900460070b80929190611b2890613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f604051611b79906134a3565b60006040518083038185875af1925050503d8060008114611bb6576040519150601f19603f3d011682016040523d82523d6000602084013e611bbb565b606091505b5050905080611bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf69061352a565b60405180910390fd5b505b61080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6186866040518363ffffffff1660e01b8152600401611c3e929190613a8f565b6000604051808303816000875af1158015611c5d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611c869190613c0c565b90508115611d855760008081819054906101000a900460070b80929190611cac90613442565b91906101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff1602179055505060008573ffffffffffffffffffffffffffffffffffffffff16600f604051611cfd906134a3565b60006040518083038185875af1925050503d8060008114611d3a576040519150601f19603f3d011682016040523d82523d6000602084013e611d3f565b606091505b5050905080611d83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7a9061352a565b60405180910390fd5b505b949350505050565b6060600061080173ffffffffffffffffffffffffffffffffffffffff16635a9d9a9633876040518363ffffffff1660e01b8152600401611dce929190613c55565b6020604051808303816000875af1158015611ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1191906135f6565b905080611e53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4a906142e8565b60405180910390fd5b61080173ffffffffffffffffffffffffffffffffffffffff1663b46a8d6185856040518363ffffffff1660e01b8152600401611e90929190613c55565b6000604051808303816000875af1158015611eaf573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ed89190613c0c565b9150509392505050565b606061080173ffffffffffffffffffffffffffffffffffffffff1663a66cb605836040518263ffffffff1660e01b8152600401611f1f919061369e565b600060405180830381865afa158015611f3c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611f6591906143e9565b9050919050565b600060016000808282829054906101000a900460070b611f8c9190614432565b92506101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff16021790555061080173ffffffffffffffffffffffffffffffffffffffff1663ed41d0b684846040518363ffffffff1660e01b8152600401611ff2929190614492565b6020604051808303816000875af1158015612011573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203591906135f6565b905060016000808282829054906101000a900460070b61205591906144bb565b92506101000a81548167ffffffffffffffff021916908360070b67ffffffffffffffff16021790555092915050565b606061080173ffffffffffffffffffffffffffffffffffffffff16635431f450836040518263ffffffff1660e01b81526004016120c1919061369e565b600060405180830381865afa1580156120de573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612107919061451b565b9050919050565b565b606061080173ffffffffffffffffffffffffffffffffffffffff166385b2d2da836040518263ffffffff1660e01b815260040161214d91906132b4565b600060405180830381865afa15801561216a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121939190613d78565b9050919050565b606061080173ffffffffffffffffffffffffffffffffffffffff16633ce4e3be836040518263ffffffff1660e01b81526004016121d791906132b4565b6000604051808303816000875af11580156121f6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061221f9190613c0c565b9050919050565b60608061080173ffffffffffffffffffffffffffffffffffffffff166354be1a28846040518263ffffffff1660e01b8152600401612264919061369e565b600060405180830381865afa158015612281573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122aa91906146cd565b91509150915091565b60405180606001604052806060815260200160608152602001606081525090565b604051806040016040528060608152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006123378261230c565b9050919050565b6123478161232c565b811461235257600080fd5b50565b6000813590506123648161233e565b92915050565b600063ffffffff82169050919050565b6123838161236a565b811461238e57600080fd5b50565b6000813590506123a08161237a565b92915050565b60008115159050919050565b6123bb816123a6565b81146123c657600080fd5b50565b6000813590506123d8816123b2565b92915050565b600080600080608085870312156123f8576123f7612302565b5b600061240687828801612355565b945050602061241787828801612391565b9350506040612428878288016123c9565b9250506060612439878288016123c9565b91505092959194509250565b60006124508261230c565b9050919050565b61246081612445565b811461246b57600080fd5b50565b60008135905061247d81612457565b92915050565b60006020828403121561249957612498612302565b5b60006124a78482850161246e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156124ea5780820151818401526020810190506124cf565b60008484015250505050565b6000601f19601f8301169050919050565b6000612512826124b0565b61251c81856124bb565b935061252c8185602086016124cc565b612535816124f6565b840191505092915050565b6000602082019050818103600083015261255a8184612507565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125a4826124f6565b810181811067ffffffffffffffff821117156125c3576125c261256c565b5b80604052505050565b60006125d66122f8565b90506125e2828261259b565b919050565b600067ffffffffffffffff8211156126025761260161256c565b5b61260b826124f6565b9050602081019050919050565b82818337600083830152505050565b600061263a612635846125e7565b6125cc565b90508281526020810184848401111561265657612655612567565b5b612661848285612618565b509392505050565b600082601f83011261267e5761267d612562565b5b813561268e848260208601612627565b91505092915050565b6000602082840312156126ad576126ac612302565b5b600082013567ffffffffffffffff8111156126cb576126ca612307565b5b6126d784828501612669565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000612707826126e0565b61271181856126eb565b93506127218185602086016124cc565b61272a816124f6565b840191505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b61277481612761565b82525050565b600060ff82169050919050565b6127908161277a565b82525050565b600060608301600083015184820360008601526127b382826126fc565b91505060208301516127c8602086018261276b565b5060408301516127db6040860182612787565b508091505092915050565b60006127f28383612796565b905092915050565b6000602082019050919050565b600061281282612735565b61281c8185612740565b93508360208202850161282e85612751565b8060005b8581101561286a578484038952815161284b85826127e6565b9450612856836127fa565b925060208a01995050600181019050612832565b50829750879550505050505092915050565b6000606083016000830151848203600086015261289982826126fc565b915050602083015184820360208601526128b38282612807565b915050604083015184820360408601526128cd8282612807565b9150508091505092915050565b600060208201905081810360008301526128f4818461287c565b905092915050565b6000806000806080858703121561291657612915612302565b5b600061292487828801612355565b945050602061293587828801612355565b935050604085013567ffffffffffffffff81111561295657612955612307565b5b61296287828801612669565b9250506060612973878288016123c9565b91505092959194509250565b6000806040838503121561299657612995612302565b5b60006129a48582860161246e565b925050602083013567ffffffffffffffff8111156129c5576129c4612307565b5b6129d185828601612669565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006040830160008301518482036000860152612a2482826126fc565b9150506020830151612a39602086018261276b565b508091505092915050565b6000612a508383612a07565b905092915050565b6000602082019050919050565b6000612a70826129db565b612a7a81856129e6565b935083602082028501612a8c856129f7565b8060005b85811015612ac85784840389528151612aa98582612a44565b9450612ab483612a58565b925060208a01995050600181019050612a90565b50829750879550505050505092915050565b60006020820190508181036000830152612af48184612a65565b905092915050565b612b05816123a6565b82525050565b6000602082019050612b206000830184612afc565b92915050565b60008060008060808587031215612b4057612b3f612302565b5b600085013567ffffffffffffffff811115612b5e57612b5d612307565b5b612b6a87828801612669565b9450506020612b7b87828801612355565b9350506040612b8c878288016123c9565b9250506060612b9d878288016123c9565b91505092959194509250565b60008160070b9050919050565b612bbf81612ba9565b82525050565b6000602082019050612bda6000830184612bb6565b92915050565b612be981612761565b8114612bf457600080fd5b50565b600081359050612c0681612be0565b92915050565b60008060008060808587031215612c2657612c25612302565b5b6000612c3487828801612355565b9450506020612c4587828801612bf7565b9350506040612c56878288016123c9565b9250506060612c67878288016123c9565b91505092959194509250565b60008060408385031215612c8a57612c89612302565b5b6000612c988582860161246e565b9250506020612ca985828601612391565b9150509250929050565b600082825260208201905092915050565b6000612ccf82612735565b612cd98185612cb3565b935083602082028501612ceb85612751565b8060005b85811015612d275784840389528151612d0885826127e6565b9450612d13836127fa565b925060208a01995050600181019050612cef565b50829750879550505050505092915050565b60006020820190508181036000830152612d538184612cc4565b905092915050565b600067ffffffffffffffff82169050919050565b612d7881612d5b565b8114612d8357600080fd5b50565b600081359050612d9581612d6f565b92915050565b600080fd5b600060a08284031215612db657612db5612d9b565b5b81905092915050565b60008060008060808587031215612dd957612dd8612302565b5b600085013567ffffffffffffffff811115612df757612df6612307565b5b612e0387828801612669565b9450506020612e1487828801612d86565b9350506040612e2587828801612d86565b925050606085013567ffffffffffffffff811115612e4657612e45612307565b5b612e5287828801612da0565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612e9381612d5b565b82525050565b604082016000820151612eaf600085018261276b565b506020820151612ec26020850182612787565b50505050565b606082016000820151612ede6000850182612e8a565b506020820151612ef16020850182612e99565b50505050565b6000612f038383612ec8565b60608301905092915050565b6000602082019050919050565b6000612f2782612e5e565b612f318185612e69565b9350612f3c83612e7a565b8060005b83811015612f6d578151612f548882612ef7565b9750612f5f83612f0f565b925050600181019050612f40565b5085935050505092915050565b600082825260208201905092915050565b6000612f96826124b0565b612fa08185612f7a565b9350612fb08185602086016124cc565b612fb9816124f6565b840191505092915050565b60006040830160008301518482036000860152612fe18282612f8b565b9150506020830151612ff66020860182612e8a565b508091505092915050565b6000604082019050818103600083015261301b8185612f1c565b9050818103602083015261302f8184612fc4565b90509392505050565b6000806000806080858703121561305257613051612302565b5b600061306087828801612355565b945050602085013567ffffffffffffffff81111561308157613080612307565b5b61308d87828801612669565b935050604061309e878288016123c9565b92505060606130af878288016123c9565b91505092959194509250565b6000806000606084860312156130d4576130d3612302565b5b600084013567ffffffffffffffff8111156130f2576130f1612307565b5b6130fe86828701612669565b935050602061310f8682870161246e565b925050604084013567ffffffffffffffff8111156131305761312f612307565b5b61313c86828701612669565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061317e83836126fc565b905092915050565b6000602082019050919050565b600061319e82613146565b6131a88185613151565b9350836020820285016131ba85613162565b8060005b858110156131f657848403895281516131d78582613172565b94506131e283613186565b925060208a019950506001810190506131be565b50829750879550505050505092915050565b600060208201905081810360008301526132228184613193565b905092915050565b6000806040838503121561324157613240612302565b5b600061324f8582860161246e565b925050602061326085828601612bf7565b9150509250929050565b600082825260208201905092915050565b6000613286826126e0565b613290818561326a565b93506132a08185602086016124cc565b6132a9816124f6565b840191505092915050565b600060208201905081810360008301526132ce818461327b565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000604083016000830151848203600086015261331f82826126fc565b915050602083015184820360208601526133398282612807565b9150508091505092915050565b60006133528383613302565b905092915050565b6000602082019050919050565b6000613372826132d6565b61337c81856132e1565b93508360208202850161338e856132f2565b8060005b858110156133ca57848403895281516133ab8582613346565b94506133b68361335a565b925060208a01995050600181019050613392565b50829750879550505050505092915050565b600060408201905081810360008301526133f68185613367565b9050818103602083015261340a8184612cc4565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061344d82612ba9565b9150677fffffffffffffff820361346757613466613413565b5b600182019050919050565b600081905092915050565b50565b600061348d600083613472565b91506134988261347d565b600082019050919050565b60006134ae82613480565b9150819050919050565b7f4661696c656420746f2073656e6420457468657220746f2064656c656761746f60008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b600061351460218361326a565b915061351f826134b8565b604082019050919050565b6000602082019050818103600083015261354381613507565b9050919050565b6000819050919050565b600061356f61356a6135658461230c565b61354a565b61230c565b9050919050565b600061358182613554565b9050919050565b600061359382613576565b9050919050565b6135a381613588565b82525050565b6135b28161236a565b82525050565b60006040820190506135cd600083018561359a565b6135da60208301846135a9565b9392505050565b6000815190506135f0816123b2565b92915050565b60006020828403121561360c5761360b612302565b5b600061361a848285016135e1565b91505092915050565b7f6661696c656420746f20636c61696d2072657761726473000000000000000000600082015250565b600061365960178361326a565b915061366482613623565b602082019050919050565b600060208201905081810360008301526136888161364c565b9050919050565b61369881612445565b82525050565b60006020820190506136b3600083018461368f565b92915050565b60006136c4826124b0565b6136ce8185613472565b93506136de8185602086016124cc565b80840191505092915050565b60006136f682846136b9565b915081905092915050565b7f6661696c65642073746174696343616c6c20746f20707265636f6d70696c6500600082015250565b6000613737601f8361326a565b915061374282613701565b602082019050919050565b600060208201905081810360008301526137668161372a565b9050919050565b600080fd5b600080fd5b600061378a613785846125e7565b6125cc565b9050828152602081018484840111156137a6576137a5612567565b5b6137b18482856124cc565b509392505050565b600082601f8301126137ce576137cd612562565b5b81516137de848260208601613777565b91505092915050565b600067ffffffffffffffff8211156138025761380161256c565b5b602082029050602081019050919050565b600080fd5b60008151905061382781612be0565b92915050565b6138368161277a565b811461384157600080fd5b50565b6000815190506138538161382d565b92915050565b60006060828403121561386f5761386e61376d565b5b61387960606125cc565b9050600082015167ffffffffffffffff81111561389957613898613772565b5b6138a5848285016137b9565b60008301525060206138b984828501613818565b60208301525060406138cd84828501613844565b60408301525092915050565b60006138ec6138e7846137e7565b6125cc565b9050808382526020820190506020840283018581111561390f5761390e613813565b5b835b8181101561395657805167ffffffffffffffff81111561393457613933612562565b5b8086016139418982613859565b85526020850194505050602081019050613911565b5050509392505050565b600082601f83011261397557613974612562565b5b81516139858482602086016138d9565b91505092915050565b6000606082840312156139a4576139a361376d565b5b6139ae60606125cc565b9050600082015167ffffffffffffffff8111156139ce576139cd613772565b5b6139da848285016137b9565b600083015250602082015167ffffffffffffffff8111156139fe576139fd613772565b5b613a0a84828501613960565b602083015250604082015167ffffffffffffffff811115613a2e57613a2d613772565b5b613a3a84828501613960565b60408301525092915050565b600060208284031215613a5c57613a5b612302565b5b600082015167ffffffffffffffff811115613a7a57613a79612307565b5b613a868482850161398e565b91505092915050565b6000604082019050613aa4600083018561359a565b8181036020830152613ab6818461327b565b90509392505050565b600067ffffffffffffffff821115613ada57613ad961256c565b5b602082029050602081019050919050565b600060408284031215613b0157613b0061376d565b5b613b0b60406125cc565b9050600082015167ffffffffffffffff811115613b2b57613b2a613772565b5b613b37848285016137b9565b6000830152506020613b4b84828501613818565b60208301525092915050565b6000613b6a613b6584613abf565b6125cc565b90508083825260208201905060208402830185811115613b8d57613b8c613813565b5b835b81811015613bd457805167ffffffffffffffff811115613bb257613bb1612562565b5b808601613bbf8982613aeb565b85526020850194505050602081019050613b8f565b5050509392505050565b600082601f830112613bf357613bf2612562565b5b8151613c03848260208601613b57565b91505092915050565b600060208284031215613c2257613c21612302565b5b600082015167ffffffffffffffff811115613c4057613c3f612307565b5b613c4c84828501613bde565b91505092915050565b6000604082019050613c6a600083018561368f565b8181036020830152613c7c818461327b565b90509392505050565b7f6661696c65642064656c656761746543616c6c20746f20707265636f6d70696c60008201527f6500000000000000000000000000000000000000000000000000000000000000602082015250565b6000613ce160218361326a565b9150613cec82613c85565b604082019050919050565b60006020820190508181036000830152613d1081613cd4565b9050919050565b613d2081612761565b82525050565b6000604082019050613d3b600083018561359a565b613d486020830184613d17565b9392505050565b6000604082019050613d64600083018561368f565b613d7160208301846135a9565b9392505050565b600060208284031215613d8e57613d8d612302565b5b600082015167ffffffffffffffff811115613dac57613dab612307565b5b613db884828501613960565b91505092915050565b613dca81612d5b565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112613dfc57613dfb613dda565b5b83810192508235915060208301925067ffffffffffffffff821115613e2457613e23613dd0565b5b600182023603831315613e3a57613e39613dd5565b5b509250929050565b6000613e4e8385612f7a565b9350613e5b838584612618565b613e64836124f6565b840190509392505050565b6000613e7e6020840184612d86565b905092915050565b6000613e9560208401846123c9565b905092915050565b613ea6816123a6565b82525050565b600060a08301613ebf6000840184613ddf565b8583036000870152613ed2838284613e42565b92505050613ee36020840184613e6f565b613ef06020860182612e8a565b50613efe6040840184613e6f565b613f0b6040860182612e8a565b50613f196060840184613e86565b613f266060860182613e9d565b50613f346080840184613e86565b613f416080860182613e9d565b508091505092915050565b60006080820190508181036000830152613f66818761327b565b9050613f756020830186613dc1565b613f826040830185613dc1565b8181036060830152613f948184613eac565b905095945050505050565b600067ffffffffffffffff821115613fba57613fb961256c565b5b602082029050602081019050919050565b600081519050613fda81612d6f565b92915050565b600060408284031215613ff657613ff561376d565b5b61400060406125cc565b9050600061401084828501613818565b600083015250602061402484828501613844565b60208301525092915050565b6000606082840312156140465761404561376d565b5b61405060406125cc565b9050600061406084828501613fcb565b600083015250602061407484828501613fe0565b60208301525092915050565b600061409361408e84613f9f565b6125cc565b905080838252602082019050606084028301858111156140b6576140b5613813565b5b835b818110156140df57806140cb8882614030565b8452602084019350506060810190506140b8565b5050509392505050565b600082601f8301126140fe576140fd612562565b5b815161410e848260208601614080565b91505092915050565b600067ffffffffffffffff8211156141325761413161256c565b5b61413b826124f6565b9050602081019050919050565b600061415b61415684614117565b6125cc565b90508281526020810184848401111561417757614176612567565b5b6141828482856124cc565b509392505050565b600082601f83011261419f5761419e612562565b5b81516141af848260208601614148565b91505092915050565b6000604082840312156141ce576141cd61376d565b5b6141d860406125cc565b9050600082015167ffffffffffffffff8111156141f8576141f7613772565b5b6142048482850161418a565b600083015250602061421884828501613fcb565b60208301525092915050565b6000806040838503121561423b5761423a612302565b5b600083015167ffffffffffffffff81111561425957614258612307565b5b614265858286016140e9565b925050602083015167ffffffffffffffff81111561428657614285612307565b5b614292858286016141b8565b9150509250929050565b7f6661696c656420746f2073657420776974686472617720616464726573730000600082015250565b60006142d2601e8361326a565b91506142dd8261429c565b602082019050919050565b60006020820190508181036000830152614301816142c5565b9050919050565b600067ffffffffffffffff8211156143235761432261256c565b5b602082029050602081019050919050565b600061434761434284614308565b6125cc565b9050808382526020820190506020840283018581111561436a57614369613813565b5b835b818110156143b157805167ffffffffffffffff81111561438f5761438e612562565b5b80860161439c89826137b9565b8552602085019450505060208101905061436c565b5050509392505050565b600082601f8301126143d0576143cf612562565b5b81516143e0848260208601614334565b91505092915050565b6000602082840312156143ff576143fe612302565b5b600082015167ffffffffffffffff81111561441d5761441c612307565b5b614429848285016143bb565b91505092915050565b600061443d82612ba9565b915061444883612ba9565b925082820190507fffffffffffffffffffffffffffffffffffffffffffffffff80000000000000008112677fffffffffffffff8213171561448c5761448b613413565b5b92915050565b60006040820190506144a7600083018561368f565b6144b46020830184613d17565b9392505050565b60006144c682612ba9565b91506144d183612ba9565b92508282039050677fffffffffffffff81137fffffffffffffffffffffffffffffffffffffffffffffffff80000000000000008212171561451557614514613413565b5b92915050565b60006020828403121561453157614530612302565b5b600082015167ffffffffffffffff81111561454f5761454e612307565b5b61455b848285016137b9565b91505092915050565b600067ffffffffffffffff82111561457f5761457e61256c565b5b602082029050602081019050919050565b6000604082840312156145a6576145a561376d565b5b6145b060406125cc565b9050600082015167ffffffffffffffff8111156145d0576145cf613772565b5b6145dc848285016137b9565b600083015250602082015167ffffffffffffffff811115614600576145ff613772565b5b61460c84828501613960565b60208301525092915050565b600061462b61462684614564565b6125cc565b9050808382526020820190506020840283018581111561464e5761464d613813565b5b835b8181101561469557805167ffffffffffffffff81111561467357614672612562565b5b8086016146808982614590565b85526020850194505050602081019050614650565b5050509392505050565b600082601f8301126146b4576146b3612562565b5b81516146c4848260208601614618565b91505092915050565b600080604083850312156146e4576146e3612302565b5b600083015167ffffffffffffffff81111561470257614701612307565b5b61470e8582860161469f565b925050602083015167ffffffffffffffff81111561472f5761472e612307565b5b61473b85828601613960565b915050925092905056fea2646970667358221220a8fdbc3760bca6bed7c0d0a8bfa4c3e75e199774f0a60a0a34530a58ee2456ed64736f6c63430008130033",
   "linkReferences": {},
   "deployedLinkReferences": {}
 }

programming_language: Jupyter Notebook
filename: FlashLoan.json
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,7 @@
 {
   "_format": "hh-sol-artifact-1",
   "contractName": "FlashLoan",
-  "sourceName": "contracts/evmos/testutil/contracts/FlashLoan.sol",
+  "sourceName": "solidity/precompiles/testutil/contracts/FlashLoan.sol",
   "abi": [
     {
       "inputs": [],
@@ -103,8 +103,8 @@
       "type": "function"
     }
   ],
-  "bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506113ea806100606000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80638da5cb5b146100515780638f5184301461006f578063ee52ad711461008b578063f12fae93146100bb575b600080fd5b6100596100eb565b6040516100669190610bdd565b60405180910390f35b61008960048036038101906100849190610db4565b61010f565b005b6100a560048036038101906100a09190610db4565b6101da565b6040516100b29190610e3e565b60405180910390f35b6100d560048036038101906100d09190610db4565b6107c9565b6040516100e29190610e3e565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061080073ffffffffffffffffffffffffffffffffffffffff166353266bbb8585856040518463ffffffff1660e01b815260040161015093929190610ee7565b6020604051808303816000875af115801561016f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101939190610f51565b9050806101d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cc90610fca565b60405180910390fd5b600080fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461026b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102629061105c565b60405180910390fd5b6000849050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b81526004016102ac92919061107c565b602060405180830381865afa1580156102c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ed91906110ba565b101561032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032590611133565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103699190610bdd565b602060405180830381865afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa91906110ba565b905060008273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b81526004016103eb93929190611153565b6020604051808303816000875af115801561040a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042e9190610f51565b905080610470576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610467906111fc565b60405180910390fd5b848261047c919061124b565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016104b59190610bdd565b602060405180830381865afa1580156104d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f691906110ba565b14610536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052d906112cb565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3388886040518463ffffffff1660e01b815260040161057593929190610ee7565b6020604051808303816000875af1158015610594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b89190610f51565b9050806105fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f190610fca565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016106339190610bdd565b602060405180830381865afa158015610650573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067491906110ba565b91508273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33876040518363ffffffff1660e01b81526004016106b19291906112eb565b6020604051808303816000875af11580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f49190610f51565b5084826107019190611314565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161073a9190610bdd565b602060405180830381865afa158015610757573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077b91906110ba565b146107bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b290611394565b60405180910390fd5b600193505050509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461085a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108519061105c565b60405180910390fd5b6000849050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b815260040161089b92919061107c565b602060405180830381865afa1580156108b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dc91906110ba565b101561091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091490611133565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109589190610bdd565b602060405180830381865afa158015610975573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099991906110ba565b905060008273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b81526004016109da93929190611153565b6020604051808303816000875af11580156109f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1d9190610f51565b905080610a5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a56906111fc565b60405180910390fd5b8482610a6b919061124b565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610aa49190610bdd565b602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae591906110ba565b14610b25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1c906112cb565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16638f5184303388886040518463ffffffff1660e01b8152600401610b6293929190610ee7565b600060405180830381600087803b158015610b7c57600080fd5b505af1925050508015610b8d575060015b50600193505050509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610bc782610b9c565b9050919050565b610bd781610bbc565b82525050565b6000602082019050610bf26000830184610bce565b92915050565b6000604051905090565b600080fd5b600080fd5b610c1581610bbc565b8114610c2057600080fd5b50565b600081359050610c3281610c0c565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610c8b82610c42565b810181811067ffffffffffffffff82111715610caa57610ca9610c53565b5b80604052505050565b6000610cbd610bf8565b9050610cc98282610c82565b919050565b600067ffffffffffffffff821115610ce957610ce8610c53565b5b610cf282610c42565b9050602081019050919050565b82818337600083830152505050565b6000610d21610d1c84610cce565b610cb3565b905082815260208101848484011115610d3d57610d3c610c3d565b5b610d48848285610cff565b509392505050565b600082601f830112610d6557610d64610c38565b5b8135610d75848260208601610d0e565b91505092915050565b6000819050919050565b610d9181610d7e565b8114610d9c57600080fd5b50565b600081359050610dae81610d88565b92915050565b600080600060608486031215610dcd57610dcc610c02565b5b6000610ddb86828701610c23565b935050602084013567ffffffffffffffff811115610dfc57610dfb610c07565b5b610e0886828701610d50565b9250506040610e1986828701610d9f565b9150509250925092565b60008115159050919050565b610e3881610e23565b82525050565b6000602082019050610e536000830184610e2f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e93578082015181840152602081019050610e78565b60008484015250505050565b6000610eaa82610e59565b610eb48185610e64565b9350610ec4818560208601610e75565b610ecd81610c42565b840191505092915050565b610ee181610d7e565b82525050565b6000606082019050610efc6000830186610bce565b8181036020830152610f0e8185610e9f565b9050610f1d6040830184610ed8565b949350505050565b610f2e81610e23565b8114610f3957600080fd5b50565b600081519050610f4b81610f25565b92915050565b600060208284031215610f6757610f66610c02565b5b6000610f7584828501610f3c565b91505092915050565b7f6661696c656420746f2064656c65676174650000000000000000000000000000600082015250565b6000610fb4601283610e64565b9150610fbf82610f7e565b602082019050919050565b60006020820190508181036000830152610fe381610fa7565b9050919050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f60008201527f6e00000000000000000000000000000000000000000000000000000000000000602082015250565b6000611046602183610e64565b915061105182610fea565b604082019050919050565b6000602082019050818103600083015261107581611039565b9050919050565b60006040820190506110916000830185610bce565b61109e6020830184610bce565b9392505050565b6000815190506110b481610d88565b92915050565b6000602082840312156110d0576110cf610c02565b5b60006110de848285016110a5565b91505092915050565b7f496e73756666696369656e7420616c6c6f77616e636500000000000000000000600082015250565b600061111d601683610e64565b9150611128826110e7565b602082019050919050565b6000602082019050818103600083015261114c81611110565b9050919050565b60006060820190506111686000830186610bce565b6111756020830185610bce565b6111826040830184610ed8565b949350505050565b7f4661696c656420746f207472616e7366657220746f6b656e7320666f7220666c60008201527f617368206c6f616e000000000000000000000000000000000000000000000000602082015250565b60006111e6602883610e64565b91506111f18261118a565b604082019050919050565b60006020820190508181036000830152611215816111d9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061125682610d7e565b915061126183610d7e565b92508282019050808211156112795761127861121c565b5b92915050565b7f466c617368206c6f616e206661696c6564000000000000000000000000000000600082015250565b60006112b5601183610e64565b91506112c08261127f565b602082019050919050565b600060208201905081810360008301526112e4816112a8565b9050919050565b60006040820190506113006000830185610bce565b61130d6020830184610ed8565b9392505050565b600061131f82610d7e565b915061132a83610d7e565b92508282039050818111156113425761134161121c565b5b92915050565b7f466c617368206c6f616e2072657061796d656e74206661696c65640000000000600082015250565b600061137e601b83610e64565b915061138982611348565b602082019050919050565b600060208201905081810360008301526113ad81611371565b905091905056fea2646970667358221220c424c19551d9b4559d960ffe973aece9d88bd266c540f629abf8f11eb26a6c1e64736f6c63430008120033",
-  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80638da5cb5b146100515780638f5184301461006f578063ee52ad711461008b578063f12fae93146100bb575b600080fd5b6100596100eb565b6040516100669190610bdd565b60405180910390f35b61008960048036038101906100849190610db4565b61010f565b005b6100a560048036038101906100a09190610db4565b6101da565b6040516100b29190610e3e565b60405180910390f35b6100d560048036038101906100d09190610db4565b6107c9565b6040516100e29190610e3e565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061080073ffffffffffffffffffffffffffffffffffffffff166353266bbb8585856040518463ffffffff1660e01b815260040161015093929190610ee7565b6020604051808303816000875af115801561016f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101939190610f51565b9050806101d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cc90610fca565b60405180910390fd5b600080fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461026b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102629061105c565b60405180910390fd5b6000849050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b81526004016102ac92919061107c565b602060405180830381865afa1580156102c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ed91906110ba565b101561032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032590611133565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103699190610bdd565b602060405180830381865afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa91906110ba565b905060008273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b81526004016103eb93929190611153565b6020604051808303816000875af115801561040a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042e9190610f51565b905080610470576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610467906111fc565b60405180910390fd5b848261047c919061124b565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016104b59190610bdd565b602060405180830381865afa1580156104d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f691906110ba565b14610536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052d906112cb565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3388886040518463ffffffff1660e01b815260040161057593929190610ee7565b6020604051808303816000875af1158015610594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b89190610f51565b9050806105fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f190610fca565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016106339190610bdd565b602060405180830381865afa158015610650573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067491906110ba565b91508273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33876040518363ffffffff1660e01b81526004016106b19291906112eb565b6020604051808303816000875af11580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f49190610f51565b5084826107019190611314565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161073a9190610bdd565b602060405180830381865afa158015610757573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077b91906110ba565b146107bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b290611394565b60405180910390fd5b600193505050509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461085a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108519061105c565b60405180910390fd5b6000849050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b815260040161089b92919061107c565b602060405180830381865afa1580156108b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dc91906110ba565b101561091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091490611133565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109589190610bdd565b602060405180830381865afa158015610975573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099991906110ba565b905060008273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b81526004016109da93929190611153565b6020604051808303816000875af11580156109f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1d9190610f51565b905080610a5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a56906111fc565b60405180910390fd5b8482610a6b919061124b565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610aa49190610bdd565b602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae591906110ba565b14610b25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1c906112cb565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16638f5184303388886040518463ffffffff1660e01b8152600401610b6293929190610ee7565b600060405180830381600087803b158015610b7c57600080fd5b505af1925050508015610b8d575060015b50600193505050509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610bc782610b9c565b9050919050565b610bd781610bbc565b82525050565b6000602082019050610bf26000830184610bce565b92915050565b6000604051905090565b600080fd5b600080fd5b610c1581610bbc565b8114610c2057600080fd5b50565b600081359050610c3281610c0c565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610c8b82610c42565b810181811067ffffffffffffffff82111715610caa57610ca9610c53565b5b80604052505050565b6000610cbd610bf8565b9050610cc98282610c82565b919050565b600067ffffffffffffffff821115610ce957610ce8610c53565b5b610cf282610c42565b9050602081019050919050565b82818337600083830152505050565b6000610d21610d1c84610cce565b610cb3565b905082815260208101848484011115610d3d57610d3c610c3d565b5b610d48848285610cff565b509392505050565b600082601f830112610d6557610d64610c38565b5b8135610d75848260208601610d0e565b91505092915050565b6000819050919050565b610d9181610d7e565b8114610d9c57600080fd5b50565b600081359050610dae81610d88565b92915050565b600080600060608486031215610dcd57610dcc610c02565b5b6000610ddb86828701610c23565b935050602084013567ffffffffffffffff811115610dfc57610dfb610c07565b5b610e0886828701610d50565b9250506040610e1986828701610d9f565b9150509250925092565b60008115159050919050565b610e3881610e23565b82525050565b6000602082019050610e536000830184610e2f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e93578082015181840152602081019050610e78565b60008484015250505050565b6000610eaa82610e59565b610eb48185610e64565b9350610ec4818560208601610e75565b610ecd81610c42565b840191505092915050565b610ee181610d7e565b82525050565b6000606082019050610efc6000830186610bce565b8181036020830152610f0e8185610e9f565b9050610f1d6040830184610ed8565b949350505050565b610f2e81610e23565b8114610f3957600080fd5b50565b600081519050610f4b81610f25565b92915050565b600060208284031215610f6757610f66610c02565b5b6000610f7584828501610f3c565b91505092915050565b7f6661696c656420746f2064656c65676174650000000000000000000000000000600082015250565b6000610fb4601283610e64565b9150610fbf82610f7e565b602082019050919050565b60006020820190508181036000830152610fe381610fa7565b9050919050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f60008201527f6e00000000000000000000000000000000000000000000000000000000000000602082015250565b6000611046602183610e64565b915061105182610fea565b604082019050919050565b6000602082019050818103600083015261107581611039565b9050919050565b60006040820190506110916000830185610bce565b61109e6020830184610bce565b9392505050565b6000815190506110b481610d88565b92915050565b6000602082840312156110d0576110cf610c02565b5b60006110de848285016110a5565b91505092915050565b7f496e73756666696369656e7420616c6c6f77616e636500000000000000000000600082015250565b600061111d601683610e64565b9150611128826110e7565b602082019050919050565b6000602082019050818103600083015261114c81611110565b9050919050565b60006060820190506111686000830186610bce565b6111756020830185610bce565b6111826040830184610ed8565b949350505050565b7f4661696c656420746f207472616e7366657220746f6b656e7320666f7220666c60008201527f617368206c6f616e000000000000000000000000000000000000000000000000602082015250565b60006111e6602883610e64565b91506111f18261118a565b604082019050919050565b60006020820190508181036000830152611215816111d9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061125682610d7e565b915061126183610d7e565b92508282019050808211156112795761127861121c565b5b92915050565b7f466c617368206c6f616e206661696c6564000000000000000000000000000000600082015250565b60006112b5601183610e64565b91506112c08261127f565b602082019050919050565b600060208201905081810360008301526112e4816112a8565b9050919050565b60006040820190506113006000830185610bce565b61130d6020830184610ed8565b9392505050565b600061131f82610d7e565b915061132a83610d7e565b92508282039050818111156113425761134161121c565b5b92915050565b7f466c617368206c6f616e2072657061796d656e74206661696c65640000000000600082015250565b600061137e601b83610e64565b915061138982611348565b602082019050919050565b600060208201905081810360008301526113ad81611371565b905091905056fea2646970667358221220c424c19551d9b4559d960ffe973aece9d88bd266c540f629abf8f11eb26a6c1e64736f6c63430008120033",
+  "bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506113ea806100606000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80638da5cb5b146100515780638f5184301461006f578063ee52ad711461008b578063f12fae93146100bb575b600080fd5b6100596100eb565b6040516100669190610bdd565b60405180910390f35b61008960048036038101906100849190610db4565b61010f565b005b6100a560048036038101906100a09190610db4565b6101da565b6040516100b29190610e3e565b60405180910390f35b6100d560048036038101906100d09190610db4565b6107c9565b6040516100e29190610e3e565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061080073ffffffffffffffffffffffffffffffffffffffff166353266bbb8585856040518463ffffffff1660e01b815260040161015093929190610ee7565b6020604051808303816000875af115801561016f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101939190610f51565b9050806101d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cc90610fca565b60405180910390fd5b600080fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461026b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102629061105c565b60405180910390fd5b6000849050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b81526004016102ac92919061107c565b602060405180830381865afa1580156102c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ed91906110ba565b101561032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032590611133565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103699190610bdd565b602060405180830381865afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa91906110ba565b905060008273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b81526004016103eb93929190611153565b6020604051808303816000875af115801561040a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042e9190610f51565b905080610470576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610467906111fc565b60405180910390fd5b848261047c919061124b565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016104b59190610bdd565b602060405180830381865afa1580156104d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f691906110ba565b14610536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052d906112cb565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3388886040518463ffffffff1660e01b815260040161057593929190610ee7565b6020604051808303816000875af1158015610594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b89190610f51565b9050806105fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f190610fca565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016106339190610bdd565b602060405180830381865afa158015610650573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067491906110ba565b91508273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33876040518363ffffffff1660e01b81526004016106b19291906112eb565b6020604051808303816000875af11580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f49190610f51565b5084826107019190611314565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161073a9190610bdd565b602060405180830381865afa158015610757573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077b91906110ba565b146107bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b290611394565b60405180910390fd5b600193505050509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461085a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108519061105c565b60405180910390fd5b6000849050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b815260040161089b92919061107c565b602060405180830381865afa1580156108b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dc91906110ba565b101561091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091490611133565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109589190610bdd565b602060405180830381865afa158015610975573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099991906110ba565b905060008273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b81526004016109da93929190611153565b6020604051808303816000875af11580156109f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1d9190610f51565b905080610a5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a56906111fc565b60405180910390fd5b8482610a6b919061124b565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610aa49190610bdd565b602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae591906110ba565b14610b25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1c906112cb565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16638f5184303388886040518463ffffffff1660e01b8152600401610b6293929190610ee7565b600060405180830381600087803b158015610b7c57600080fd5b505af1925050508015610b8d575060015b50600193505050509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610bc782610b9c565b9050919050565b610bd781610bbc565b82525050565b6000602082019050610bf26000830184610bce565b92915050565b6000604051905090565b600080fd5b600080fd5b610c1581610bbc565b8114610c2057600080fd5b50565b600081359050610c3281610c0c565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610c8b82610c42565b810181811067ffffffffffffffff82111715610caa57610ca9610c53565b5b80604052505050565b6000610cbd610bf8565b9050610cc98282610c82565b919050565b600067ffffffffffffffff821115610ce957610ce8610c53565b5b610cf282610c42565b9050602081019050919050565b82818337600083830152505050565b6000610d21610d1c84610cce565b610cb3565b905082815260208101848484011115610d3d57610d3c610c3d565b5b610d48848285610cff565b509392505050565b600082601f830112610d6557610d64610c38565b5b8135610d75848260208601610d0e565b91505092915050565b6000819050919050565b610d9181610d7e565b8114610d9c57600080fd5b50565b600081359050610dae81610d88565b92915050565b600080600060608486031215610dcd57610dcc610c02565b5b6000610ddb86828701610c23565b935050602084013567ffffffffffffffff811115610dfc57610dfb610c07565b5b610e0886828701610d50565b9250506040610e1986828701610d9f565b9150509250925092565b60008115159050919050565b610e3881610e23565b82525050565b6000602082019050610e536000830184610e2f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e93578082015181840152602081019050610e78565b60008484015250505050565b6000610eaa82610e59565b610eb48185610e64565b9350610ec4818560208601610e75565b610ecd81610c42565b840191505092915050565b610ee181610d7e565b82525050565b6000606082019050610efc6000830186610bce565b8181036020830152610f0e8185610e9f565b9050610f1d6040830184610ed8565b949350505050565b610f2e81610e23565b8114610f3957600080fd5b50565b600081519050610f4b81610f25565b92915050565b600060208284031215610f6757610f66610c02565b5b6000610f7584828501610f3c565b91505092915050565b7f6661696c656420746f2064656c65676174650000000000000000000000000000600082015250565b6000610fb4601283610e64565b9150610fbf82610f7e565b602082019050919050565b60006020820190508181036000830152610fe381610fa7565b9050919050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f60008201527f6e00000000000000000000000000000000000000000000000000000000000000602082015250565b6000611046602183610e64565b915061105182610fea565b604082019050919050565b6000602082019050818103600083015261107581611039565b9050919050565b60006040820190506110916000830185610bce565b61109e6020830184610bce565b9392505050565b6000815190506110b481610d88565b92915050565b6000602082840312156110d0576110cf610c02565b5b60006110de848285016110a5565b91505092915050565b7f496e73756666696369656e7420616c6c6f77616e636500000000000000000000600082015250565b600061111d601683610e64565b9150611128826110e7565b602082019050919050565b6000602082019050818103600083015261114c81611110565b9050919050565b60006060820190506111686000830186610bce565b6111756020830185610bce565b6111826040830184610ed8565b949350505050565b7f4661696c656420746f207472616e7366657220746f6b656e7320666f7220666c60008201527f617368206c6f616e000000000000000000000000000000000000000000000000602082015250565b60006111e6602883610e64565b91506111f18261118a565b604082019050919050565b60006020820190508181036000830152611215816111d9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061125682610d7e565b915061126183610d7e565b92508282019050808211156112795761127861121c565b5b92915050565b7f466c617368206c6f616e206661696c6564000000000000000000000000000000600082015250565b60006112b5601183610e64565b91506112c08261127f565b602082019050919050565b600060208201905081810360008301526112e4816112a8565b9050919050565b60006040820190506113006000830185610bce565b61130d6020830184610ed8565b9392505050565b600061131f82610d7e565b915061132a83610d7e565b92508282039050818111156113425761134161121c565b5b92915050565b7f466c617368206c6f616e2072657061796d656e74206661696c65640000000000600082015250565b600061137e601b83610e64565b915061138982611348565b602082019050919050565b600060208201905081810360008301526113ad81611371565b905091905056fea26469706673582212208e1d52c36a32622af075b98cf15a237fb7323d1e2ace6e9cb8d762d107b21e9864736f6c63430008130033",
+  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80638da5cb5b146100515780638f5184301461006f578063ee52ad711461008b578063f12fae93146100bb575b600080fd5b6100596100eb565b6040516100669190610bdd565b60405180910390f35b61008960048036038101906100849190610db4565b61010f565b005b6100a560048036038101906100a09190610db4565b6101da565b6040516100b29190610e3e565b60405180910390f35b6100d560048036038101906100d09190610db4565b6107c9565b6040516100e29190610e3e565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061080073ffffffffffffffffffffffffffffffffffffffff166353266bbb8585856040518463ffffffff1660e01b815260040161015093929190610ee7565b6020604051808303816000875af115801561016f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101939190610f51565b9050806101d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cc90610fca565b60405180910390fd5b600080fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461026b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102629061105c565b60405180910390fd5b6000849050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b81526004016102ac92919061107c565b602060405180830381865afa1580156102c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ed91906110ba565b101561032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032590611133565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103699190610bdd565b602060405180830381865afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa91906110ba565b905060008273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b81526004016103eb93929190611153565b6020604051808303816000875af115801561040a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042e9190610f51565b905080610470576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610467906111fc565b60405180910390fd5b848261047c919061124b565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016104b59190610bdd565b602060405180830381865afa1580156104d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f691906110ba565b14610536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052d906112cb565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3388886040518463ffffffff1660e01b815260040161057593929190610ee7565b6020604051808303816000875af1158015610594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b89190610f51565b9050806105fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f190610fca565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016106339190610bdd565b602060405180830381865afa158015610650573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067491906110ba565b91508273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33876040518363ffffffff1660e01b81526004016106b19291906112eb565b6020604051808303816000875af11580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f49190610f51565b5084826107019190611314565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161073a9190610bdd565b602060405180830381865afa158015610757573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077b91906110ba565b146107bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b290611394565b60405180910390fd5b600193505050509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461085a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108519061105c565b60405180910390fd5b6000849050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b815260040161089b92919061107c565b602060405180830381865afa1580156108b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dc91906110ba565b101561091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091490611133565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109589190610bdd565b602060405180830381865afa158015610975573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099991906110ba565b905060008273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b81526004016109da93929190611153565b6020604051808303816000875af11580156109f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1d9190610f51565b905080610a5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a56906111fc565b60405180910390fd5b8482610a6b919061124b565b8373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610aa49190610bdd565b602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae591906110ba565b14610b25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1c906112cb565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16638f5184303388886040518463ffffffff1660e01b8152600401610b6293929190610ee7565b600060405180830381600087803b158015610b7c57600080fd5b505af1925050508015610b8d575060015b50600193505050509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610bc782610b9c565b9050919050565b610bd781610bbc565b82525050565b6000602082019050610bf26000830184610bce565b92915050565b6000604051905090565b600080fd5b600080fd5b610c1581610bbc565b8114610c2057600080fd5b50565b600081359050610c3281610c0c565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610c8b82610c42565b810181811067ffffffffffffffff82111715610caa57610ca9610c53565b5b80604052505050565b6000610cbd610bf8565b9050610cc98282610c82565b919050565b600067ffffffffffffffff821115610ce957610ce8610c53565b5b610cf282610c42565b9050602081019050919050565b82818337600083830152505050565b6000610d21610d1c84610cce565b610cb3565b905082815260208101848484011115610d3d57610d3c610c3d565b5b610d48848285610cff565b509392505050565b600082601f830112610d6557610d64610c38565b5b8135610d75848260208601610d0e565b91505092915050565b6000819050919050565b610d9181610d7e565b8114610d9c57600080fd5b50565b600081359050610dae81610d88565b92915050565b600080600060608486031215610dcd57610dcc610c02565b5b6000610ddb86828701610c23565b935050602084013567ffffffffffffffff811115610dfc57610dfb610c07565b5b610e0886828701610d50565b9250506040610e1986828701610d9f565b9150509250925092565b60008115159050919050565b610e3881610e23565b82525050565b6000602082019050610e536000830184610e2f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e93578082015181840152602081019050610e78565b60008484015250505050565b6000610eaa82610e59565b610eb48185610e64565b9350610ec4818560208601610e75565b610ecd81610c42565b840191505092915050565b610ee181610d7e565b82525050565b6000606082019050610efc6000830186610bce565b8181036020830152610f0e8185610e9f565b9050610f1d6040830184610ed8565b949350505050565b610f2e81610e23565b8114610f3957600080fd5b50565b600081519050610f4b81610f25565b92915050565b600060208284031215610f6757610f66610c02565b5b6000610f7584828501610f3c565b91505092915050565b7f6661696c656420746f2064656c65676174650000000000000000000000000000600082015250565b6000610fb4601283610e64565b9150610fbf82610f7e565b602082019050919050565b60006020820190508181036000830152610fe381610fa7565b9050919050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f60008201527f6e00000000000000000000000000000000000000000000000000000000000000602082015250565b6000611046602183610e64565b915061105182610fea565b604082019050919050565b6000602082019050818103600083015261107581611039565b9050919050565b60006040820190506110916000830185610bce565b61109e6020830184610bce565b9392505050565b6000815190506110b481610d88565b92915050565b6000602082840312156110d0576110cf610c02565b5b60006110de848285016110a5565b91505092915050565b7f496e73756666696369656e7420616c6c6f77616e636500000000000000000000600082015250565b600061111d601683610e64565b9150611128826110e7565b602082019050919050565b6000602082019050818103600083015261114c81611110565b9050919050565b60006060820190506111686000830186610bce565b6111756020830185610bce565b6111826040830184610ed8565b949350505050565b7f4661696c656420746f207472616e7366657220746f6b656e7320666f7220666c60008201527f617368206c6f616e000000000000000000000000000000000000000000000000602082015250565b60006111e6602883610e64565b91506111f18261118a565b604082019050919050565b60006020820190508181036000830152611215816111d9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061125682610d7e565b915061126183610d7e565b92508282019050808211156112795761127861121c565b5b92915050565b7f466c617368206c6f616e206661696c6564000000000000000000000000000000600082015250565b60006112b5601183610e64565b91506112c08261127f565b602082019050919050565b600060208201905081810360008301526112e4816112a8565b9050919050565b60006040820190506113006000830185610bce565b61130d6020830184610ed8565b9392505050565b600061131f82610d7e565b915061132a83610d7e565b92508282039050818111156113425761134161121c565b5b92915050565b7f466c617368206c6f616e2072657061796d656e74206661696c65640000000000600082015250565b600061137e601b83610e64565b915061138982611348565b602082019050919050565b600060208201905081810360008301526113ad81611371565b905091905056fea26469706673582212208e1d52c36a32622af075b98cf15a237fb7323d1e2ace6e9cb8d762d107b21e9864736f6c63430008130033",
   "linkReferences": {},
   "deployedLinkReferences": {}
 }

programming_language: Lua
filename: FlashLoan.sol
change_type: ModificationType.MODIFY
diff: @@ -28,7 +28,7 @@ contract FlashLoan {
         uint256 balancePre = token.balanceOf(address(this));
         bool success = token.transferFrom(msg.sender, address(this), _amount);
         require(success, "Failed to transfer tokens for flash loan");
-        assert(
+        require(
             token.balanceOf(address(this)) == balancePre + _amount,
             "Flash loan failed"
         );
@@ -44,7 +44,7 @@ contract FlashLoan {
         // Transfer tokens back to end the flash loan
         balancePre = token.balanceOf(address(this));
         token.transfer(msg.sender, _amount);
-        assert(
+        require(
             token.balanceOf(address(this)) == balancePre - _amount,
             "Flash loan repayment failed"
         );
@@ -69,7 +69,7 @@ contract FlashLoan {
         uint256 balancePre = token.balanceOf(address(this));
         bool success = token.transferFrom(msg.sender, address(this), _amount);
         require(success, "Failed to transfer tokens for flash loan");
-        assert(
+        require(
             token.balanceOf(address(this)) == balancePre + _amount,
             "Flash loan failed"
         );

programming_language: JavaScript
filename: ICounter.sol
change_type: ModificationType.ADD
diff: @@ -0,0 +1,9 @@
+pragma solidity ^0.8.17;
+
+interface ICounter {
+    function add() external;
+    function subtract() external;
+    function getCounter() external view returns (uint256);
+    event Changed(uint256 counter);
+    event Added(uint256 counter);
+}

programming_language: Matlab
filename: Reverter.json
change_type: ModificationType.MODIFY
diff: @@ -38,8 +38,8 @@
       "type": "receive"
     }
   ],
-  "bytecode": "0x608060405260008055610c17806100176000396000f3fe60806040526004361061002d5760003560e01c806379388e9414610039578063c04062261461006257610034565b3661003457005b600080fd5b34801561004557600080fd5b50610060600480360381019061005b9190610360565b610079565b005b34801561006e57600080fd5b50610077610131565b005b808290604051610088906102d4565b82906040518091039083f590509050801580156100a9573d6000803e3d6000fd5b505061080173ffffffffffffffffffffffffffffffffffffffff166354be1a28306040518263ffffffff1660e01b81526004016100e691906103e1565b600060405180830381865afa158015610103573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061012c9190610884565b600080fd5b6000808154809291906101439061092b565b91905055503073ffffffffffffffffffffffffffffffffffffffff166379388e9460005460001b476040518363ffffffff1660e01b8152600401610188929190610991565b600060405180830381600087803b1580156101a257600080fd5b505af19250505080156101b3575060015b61022f5760006101c760005460001b610249565b90508073ffffffffffffffffffffffffffffffffffffffff16633ccfd60b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561021157600080fd5b505af1158015610225573d6000803e3d6000fd5b5050505050610230565b5b6000808154809291906102429061092b565b9190505550565b60008060ff60f81b308460405180602001610263906102d4565b6020820181038252601f19601f820116604052506040516020016102879190610a01565b604051602081830303815290604052805190602001206040516020016102b09493929190610ace565b6040516020818303038152906040528051906020012060001c905080915050919050565b60c580610b1d83390190565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610307816102f4565b811461031257600080fd5b50565b600081359050610324816102fe565b92915050565b6000819050919050565b61033d8161032a565b811461034857600080fd5b50565b60008135905061035a81610334565b92915050565b60008060408385031215610377576103766102ea565b5b600061038585828601610315565b92505060206103968582860161034b565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006103cb826103a0565b9050919050565b6103db816103c0565b82525050565b60006020820190506103f660008301846103d2565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61044a82610401565b810181811067ffffffffffffffff8211171561046957610468610412565b5b80604052505050565b600061047c6102e0565b90506104888282610441565b919050565b600067ffffffffffffffff8211156104a8576104a7610412565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff8211156104e8576104e7610412565b5b6104f182610401565b9050602081019050919050565b60005b8381101561051c578082015181840152602081019050610501565b60008484015250505050565b600061053b610536846104cd565b610472565b905082815260208101848484011115610557576105566104c8565b5b6105628482856104fe565b509392505050565b600082601f83011261057f5761057e6103fc565b5b815161058f848260208601610528565b91505092915050565b600067ffffffffffffffff8211156105b3576105b2610412565b5b602082029050602081019050919050565b6000815190506105d381610334565b92915050565b600060ff82169050919050565b6105ef816105d9565b81146105fa57600080fd5b50565b60008151905061060c816105e6565b92915050565b600060608284031215610628576106276104be565b5b6106326060610472565b9050600082015167ffffffffffffffff811115610652576106516104c3565b5b61065e8482850161056a565b6000830152506020610672848285016105c4565b6020830152506040610686848285016105fd565b60408301525092915050565b60006106a56106a084610598565b610472565b905080838252602082019050602084028301858111156106c8576106c76104b9565b5b835b8181101561070f57805167ffffffffffffffff8111156106ed576106ec6103fc565b5b8086016106fa8982610612565b855260208501945050506020810190506106ca565b5050509392505050565b600082601f83011261072e5761072d6103fc565b5b815161073e848260208601610692565b91505092915050565b60006040828403121561075d5761075c6104be565b5b6107676040610472565b9050600082015167ffffffffffffffff811115610787576107866104c3565b5b6107938482850161056a565b600083015250602082015167ffffffffffffffff8111156107b7576107b66104c3565b5b6107c384828501610719565b60208301525092915050565b60006107e26107dd8461048d565b610472565b90508083825260208201905060208402830185811115610805576108046104b9565b5b835b8181101561084c57805167ffffffffffffffff81111561082a576108296103fc565b5b8086016108378982610747565b85526020850194505050602081019050610807565b5050509392505050565b600082601f83011261086b5761086a6103fc565b5b815161087b8482602086016107cf565b91505092915050565b6000806040838503121561089b5761089a6102ea565b5b600083015167ffffffffffffffff8111156108b9576108b86102ef565b5b6108c585828601610856565b925050602083015167ffffffffffffffff8111156108e6576108e56102ef565b5b6108f285828601610719565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006109368261032a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610968576109676108fc565b5b600182019050919050565b61097c816102f4565b82525050565b61098b8161032a565b82525050565b60006040820190506109a66000830185610973565b6109b36020830184610982565b9392505050565b600081519050919050565b600081905092915050565b60006109db826109ba565b6109e581856109c5565b93506109f58185602086016104fe565b80840191505092915050565b6000610a0d82846109d0565b915081905092915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b610a5f610a5a82610a18565b610a44565b82525050565b60008160601b9050919050565b6000610a7d82610a65565b9050919050565b6000610a8f82610a72565b9050919050565b610aa7610aa2826103c0565b610a84565b82525050565b6000819050919050565b610ac8610ac3826102f4565b610aad565b82525050565b6000610ada8287610a4e565b600182019150610aea8286610a96565b601482019150610afa8285610ab7565b602082019150610b0a8284610ab7565b6020820191508190509594505050505056fe608060405260b3806100126000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633ccfd60b14602d575b600080fd5b60336035565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015607a573d6000803e3d6000fd5b5056fea264697066735822122008001b1cb780fb8c81d5ab538ccbeab143f74b68ef571f3c5d058a2620bf412864736f6c63430008130033a2646970667358221220a5fd3d44b59916cad19784e497c1dbfaa58f7fb8006170e93ea2c8bd32af7b0264736f6c63430008130033",
-  "deployedBytecode": "0x60806040526004361061002d5760003560e01c806379388e9414610039578063c04062261461006257610034565b3661003457005b600080fd5b34801561004557600080fd5b50610060600480360381019061005b9190610360565b610079565b005b34801561006e57600080fd5b50610077610131565b005b808290604051610088906102d4565b82906040518091039083f590509050801580156100a9573d6000803e3d6000fd5b505061080173ffffffffffffffffffffffffffffffffffffffff166354be1a28306040518263ffffffff1660e01b81526004016100e691906103e1565b600060405180830381865afa158015610103573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061012c9190610884565b600080fd5b6000808154809291906101439061092b565b91905055503073ffffffffffffffffffffffffffffffffffffffff166379388e9460005460001b476040518363ffffffff1660e01b8152600401610188929190610991565b600060405180830381600087803b1580156101a257600080fd5b505af19250505080156101b3575060015b61022f5760006101c760005460001b610249565b90508073ffffffffffffffffffffffffffffffffffffffff16633ccfd60b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561021157600080fd5b505af1158015610225573d6000803e3d6000fd5b5050505050610230565b5b6000808154809291906102429061092b565b9190505550565b60008060ff60f81b308460405180602001610263906102d4565b6020820181038252601f19601f820116604052506040516020016102879190610a01565b604051602081830303815290604052805190602001206040516020016102b09493929190610ace565b6040516020818303038152906040528051906020012060001c905080915050919050565b60c580610b1d83390190565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610307816102f4565b811461031257600080fd5b50565b600081359050610324816102fe565b92915050565b6000819050919050565b61033d8161032a565b811461034857600080fd5b50565b60008135905061035a81610334565b92915050565b60008060408385031215610377576103766102ea565b5b600061038585828601610315565b92505060206103968582860161034b565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006103cb826103a0565b9050919050565b6103db816103c0565b82525050565b60006020820190506103f660008301846103d2565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61044a82610401565b810181811067ffffffffffffffff8211171561046957610468610412565b5b80604052505050565b600061047c6102e0565b90506104888282610441565b919050565b600067ffffffffffffffff8211156104a8576104a7610412565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff8211156104e8576104e7610412565b5b6104f182610401565b9050602081019050919050565b60005b8381101561051c578082015181840152602081019050610501565b60008484015250505050565b600061053b610536846104cd565b610472565b905082815260208101848484011115610557576105566104c8565b5b6105628482856104fe565b509392505050565b600082601f83011261057f5761057e6103fc565b5b815161058f848260208601610528565b91505092915050565b600067ffffffffffffffff8211156105b3576105b2610412565b5b602082029050602081019050919050565b6000815190506105d381610334565b92915050565b600060ff82169050919050565b6105ef816105d9565b81146105fa57600080fd5b50565b60008151905061060c816105e6565b92915050565b600060608284031215610628576106276104be565b5b6106326060610472565b9050600082015167ffffffffffffffff811115610652576106516104c3565b5b61065e8482850161056a565b6000830152506020610672848285016105c4565b6020830152506040610686848285016105fd565b60408301525092915050565b60006106a56106a084610598565b610472565b905080838252602082019050602084028301858111156106c8576106c76104b9565b5b835b8181101561070f57805167ffffffffffffffff8111156106ed576106ec6103fc565b5b8086016106fa8982610612565b855260208501945050506020810190506106ca565b5050509392505050565b600082601f83011261072e5761072d6103fc565b5b815161073e848260208601610692565b91505092915050565b60006040828403121561075d5761075c6104be565b5b6107676040610472565b9050600082015167ffffffffffffffff811115610787576107866104c3565b5b6107938482850161056a565b600083015250602082015167ffffffffffffffff8111156107b7576107b66104c3565b5b6107c384828501610719565b60208301525092915050565b60006107e26107dd8461048d565b610472565b90508083825260208201905060208402830185811115610805576108046104b9565b5b835b8181101561084c57805167ffffffffffffffff81111561082a576108296103fc565b5b8086016108378982610747565b85526020850194505050602081019050610807565b5050509392505050565b600082601f83011261086b5761086a6103fc565b5b815161087b8482602086016107cf565b91505092915050565b6000806040838503121561089b5761089a6102ea565b5b600083015167ffffffffffffffff8111156108b9576108b86102ef565b5b6108c585828601610856565b925050602083015167ffffffffffffffff8111156108e6576108e56102ef565b5b6108f285828601610719565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006109368261032a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610968576109676108fc565b5b600182019050919050565b61097c816102f4565b82525050565b61098b8161032a565b82525050565b60006040820190506109a66000830185610973565b6109b36020830184610982565b9392505050565b600081519050919050565b600081905092915050565b60006109db826109ba565b6109e581856109c5565b93506109f58185602086016104fe565b80840191505092915050565b6000610a0d82846109d0565b915081905092915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b610a5f610a5a82610a18565b610a44565b82525050565b60008160601b9050919050565b6000610a7d82610a65565b9050919050565b6000610a8f82610a72565b9050919050565b610aa7610aa2826103c0565b610a84565b82525050565b6000819050919050565b610ac8610ac3826102f4565b610aad565b82525050565b6000610ada8287610a4e565b600182019150610aea8286610a96565b601482019150610afa8285610ab7565b602082019150610b0a8284610ab7565b6020820191508190509594505050505056fe608060405260b3806100126000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633ccfd60b14602d575b600080fd5b60336035565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015607a573d6000803e3d6000fd5b5056fea264697066735822122008001b1cb780fb8c81d5ab538ccbeab143f74b68ef571f3c5d058a2620bf412864736f6c63430008130033a2646970667358221220a5fd3d44b59916cad19784e497c1dbfaa58f7fb8006170e93ea2c8bd32af7b0264736f6c63430008130033",
+  "bytecode": "0x608060405260008055610c17806100176000396000f3fe60806040526004361061002d5760003560e01c806379388e9414610039578063c04062261461006257610034565b3661003457005b600080fd5b34801561004557600080fd5b50610060600480360381019061005b9190610360565b610079565b005b34801561006e57600080fd5b50610077610131565b005b808290604051610088906102d4565b82906040518091039083f590509050801580156100a9573d6000803e3d6000fd5b505061080173ffffffffffffffffffffffffffffffffffffffff166354be1a28306040518263ffffffff1660e01b81526004016100e691906103e1565b600060405180830381865afa158015610103573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061012c9190610884565b600080fd5b6000808154809291906101439061092b565b91905055503073ffffffffffffffffffffffffffffffffffffffff166379388e9460005460001b476040518363ffffffff1660e01b8152600401610188929190610991565b600060405180830381600087803b1580156101a257600080fd5b505af19250505080156101b3575060015b61022f5760006101c760005460001b610249565b90508073ffffffffffffffffffffffffffffffffffffffff16633ccfd60b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561021157600080fd5b505af1158015610225573d6000803e3d6000fd5b5050505050610230565b5b6000808154809291906102429061092b565b9190505550565b60008060ff60f81b308460405180602001610263906102d4565b6020820181038252601f19601f820116604052506040516020016102879190610a01565b604051602081830303815290604052805190602001206040516020016102b09493929190610ace565b6040516020818303038152906040528051906020012060001c905080915050919050565b60c580610b1d83390190565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610307816102f4565b811461031257600080fd5b50565b600081359050610324816102fe565b92915050565b6000819050919050565b61033d8161032a565b811461034857600080fd5b50565b60008135905061035a81610334565b92915050565b60008060408385031215610377576103766102ea565b5b600061038585828601610315565b92505060206103968582860161034b565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006103cb826103a0565b9050919050565b6103db816103c0565b82525050565b60006020820190506103f660008301846103d2565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61044a82610401565b810181811067ffffffffffffffff8211171561046957610468610412565b5b80604052505050565b600061047c6102e0565b90506104888282610441565b919050565b600067ffffffffffffffff8211156104a8576104a7610412565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff8211156104e8576104e7610412565b5b6104f182610401565b9050602081019050919050565b60005b8381101561051c578082015181840152602081019050610501565b60008484015250505050565b600061053b610536846104cd565b610472565b905082815260208101848484011115610557576105566104c8565b5b6105628482856104fe565b509392505050565b600082601f83011261057f5761057e6103fc565b5b815161058f848260208601610528565b91505092915050565b600067ffffffffffffffff8211156105b3576105b2610412565b5b602082029050602081019050919050565b6000815190506105d381610334565b92915050565b600060ff82169050919050565b6105ef816105d9565b81146105fa57600080fd5b50565b60008151905061060c816105e6565b92915050565b600060608284031215610628576106276104be565b5b6106326060610472565b9050600082015167ffffffffffffffff811115610652576106516104c3565b5b61065e8482850161056a565b6000830152506020610672848285016105c4565b6020830152506040610686848285016105fd565b60408301525092915050565b60006106a56106a084610598565b610472565b905080838252602082019050602084028301858111156106c8576106c76104b9565b5b835b8181101561070f57805167ffffffffffffffff8111156106ed576106ec6103fc565b5b8086016106fa8982610612565b855260208501945050506020810190506106ca565b5050509392505050565b600082601f83011261072e5761072d6103fc565b5b815161073e848260208601610692565b91505092915050565b60006040828403121561075d5761075c6104be565b5b6107676040610472565b9050600082015167ffffffffffffffff811115610787576107866104c3565b5b6107938482850161056a565b600083015250602082015167ffffffffffffffff8111156107b7576107b66104c3565b5b6107c384828501610719565b60208301525092915050565b60006107e26107dd8461048d565b610472565b90508083825260208201905060208402830185811115610805576108046104b9565b5b835b8181101561084c57805167ffffffffffffffff81111561082a576108296103fc565b5b8086016108378982610747565b85526020850194505050602081019050610807565b5050509392505050565b600082601f83011261086b5761086a6103fc565b5b815161087b8482602086016107cf565b91505092915050565b6000806040838503121561089b5761089a6102ea565b5b600083015167ffffffffffffffff8111156108b9576108b86102ef565b5b6108c585828601610856565b925050602083015167ffffffffffffffff8111156108e6576108e56102ef565b5b6108f285828601610719565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006109368261032a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610968576109676108fc565b5b600182019050919050565b61097c816102f4565b82525050565b61098b8161032a565b82525050565b60006040820190506109a66000830185610973565b6109b36020830184610982565b9392505050565b600081519050919050565b600081905092915050565b60006109db826109ba565b6109e581856109c5565b93506109f58185602086016104fe565b80840191505092915050565b6000610a0d82846109d0565b915081905092915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b610a5f610a5a82610a18565b610a44565b82525050565b60008160601b9050919050565b6000610a7d82610a65565b9050919050565b6000610a8f82610a72565b9050919050565b610aa7610aa2826103c0565b610a84565b82525050565b6000819050919050565b610ac8610ac3826102f4565b610aad565b82525050565b6000610ada8287610a4e565b600182019150610aea8286610a96565b601482019150610afa8285610ab7565b602082019150610b0a8284610ab7565b6020820191508190509594505050505056fe608060405260b3806100126000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633ccfd60b14602d575b600080fd5b60336035565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015607a573d6000803e3d6000fd5b5056fea26469706673582212200cca7e94767cc41a8eff494693f692a362784efcf8724ef105e5c5948d07a98a64736f6c63430008130033a26469706673582212209eedc0bf8ca98ddf4547c45c1938b3294a8c876293b916e6991af709591c556764736f6c63430008130033",
+  "deployedBytecode": "0x60806040526004361061002d5760003560e01c806379388e9414610039578063c04062261461006257610034565b3661003457005b600080fd5b34801561004557600080fd5b50610060600480360381019061005b9190610360565b610079565b005b34801561006e57600080fd5b50610077610131565b005b808290604051610088906102d4565b82906040518091039083f590509050801580156100a9573d6000803e3d6000fd5b505061080173ffffffffffffffffffffffffffffffffffffffff166354be1a28306040518263ffffffff1660e01b81526004016100e691906103e1565b600060405180830381865afa158015610103573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061012c9190610884565b600080fd5b6000808154809291906101439061092b565b91905055503073ffffffffffffffffffffffffffffffffffffffff166379388e9460005460001b476040518363ffffffff1660e01b8152600401610188929190610991565b600060405180830381600087803b1580156101a257600080fd5b505af19250505080156101b3575060015b61022f5760006101c760005460001b610249565b90508073ffffffffffffffffffffffffffffffffffffffff16633ccfd60b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561021157600080fd5b505af1158015610225573d6000803e3d6000fd5b5050505050610230565b5b6000808154809291906102429061092b565b9190505550565b60008060ff60f81b308460405180602001610263906102d4565b6020820181038252601f19601f820116604052506040516020016102879190610a01565b604051602081830303815290604052805190602001206040516020016102b09493929190610ace565b6040516020818303038152906040528051906020012060001c905080915050919050565b60c580610b1d83390190565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610307816102f4565b811461031257600080fd5b50565b600081359050610324816102fe565b92915050565b6000819050919050565b61033d8161032a565b811461034857600080fd5b50565b60008135905061035a81610334565b92915050565b60008060408385031215610377576103766102ea565b5b600061038585828601610315565b92505060206103968582860161034b565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006103cb826103a0565b9050919050565b6103db816103c0565b82525050565b60006020820190506103f660008301846103d2565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61044a82610401565b810181811067ffffffffffffffff8211171561046957610468610412565b5b80604052505050565b600061047c6102e0565b90506104888282610441565b919050565b600067ffffffffffffffff8211156104a8576104a7610412565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff8211156104e8576104e7610412565b5b6104f182610401565b9050602081019050919050565b60005b8381101561051c578082015181840152602081019050610501565b60008484015250505050565b600061053b610536846104cd565b610472565b905082815260208101848484011115610557576105566104c8565b5b6105628482856104fe565b509392505050565b600082601f83011261057f5761057e6103fc565b5b815161058f848260208601610528565b91505092915050565b600067ffffffffffffffff8211156105b3576105b2610412565b5b602082029050602081019050919050565b6000815190506105d381610334565b92915050565b600060ff82169050919050565b6105ef816105d9565b81146105fa57600080fd5b50565b60008151905061060c816105e6565b92915050565b600060608284031215610628576106276104be565b5b6106326060610472565b9050600082015167ffffffffffffffff811115610652576106516104c3565b5b61065e8482850161056a565b6000830152506020610672848285016105c4565b6020830152506040610686848285016105fd565b60408301525092915050565b60006106a56106a084610598565b610472565b905080838252602082019050602084028301858111156106c8576106c76104b9565b5b835b8181101561070f57805167ffffffffffffffff8111156106ed576106ec6103fc565b5b8086016106fa8982610612565b855260208501945050506020810190506106ca565b5050509392505050565b600082601f83011261072e5761072d6103fc565b5b815161073e848260208601610692565b91505092915050565b60006040828403121561075d5761075c6104be565b5b6107676040610472565b9050600082015167ffffffffffffffff811115610787576107866104c3565b5b6107938482850161056a565b600083015250602082015167ffffffffffffffff8111156107b7576107b66104c3565b5b6107c384828501610719565b60208301525092915050565b60006107e26107dd8461048d565b610472565b90508083825260208201905060208402830185811115610805576108046104b9565b5b835b8181101561084c57805167ffffffffffffffff81111561082a576108296103fc565b5b8086016108378982610747565b85526020850194505050602081019050610807565b5050509392505050565b600082601f83011261086b5761086a6103fc565b5b815161087b8482602086016107cf565b91505092915050565b6000806040838503121561089b5761089a6102ea565b5b600083015167ffffffffffffffff8111156108b9576108b86102ef565b5b6108c585828601610856565b925050602083015167ffffffffffffffff8111156108e6576108e56102ef565b5b6108f285828601610719565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006109368261032a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610968576109676108fc565b5b600182019050919050565b61097c816102f4565b82525050565b61098b8161032a565b82525050565b60006040820190506109a66000830185610973565b6109b36020830184610982565b9392505050565b600081519050919050565b600081905092915050565b60006109db826109ba565b6109e581856109c5565b93506109f58185602086016104fe565b80840191505092915050565b6000610a0d82846109d0565b915081905092915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b610a5f610a5a82610a18565b610a44565b82525050565b60008160601b9050919050565b6000610a7d82610a65565b9050919050565b6000610a8f82610a72565b9050919050565b610aa7610aa2826103c0565b610a84565b82525050565b6000819050919050565b610ac8610ac3826102f4565b610aad565b82525050565b6000610ada8287610a4e565b600182019150610aea8286610a96565b601482019150610afa8285610ab7565b602082019150610b0a8284610ab7565b6020820191508190509594505050505056fe608060405260b3806100126000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633ccfd60b14602d575b600080fd5b60336035565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015607a573d6000803e3d6000fd5b5056fea26469706673582212200cca7e94767cc41a8eff494693f692a362784efcf8724ef105e5c5948d07a98a64736f6c63430008130033a26469706673582212209eedc0bf8ca98ddf4547c45c1938b3294a8c876293b916e6991af709591c556764736f6c63430008130033",
   "linkReferences": {},
   "deployedLinkReferences": {}
 }

programming_language: Lua
filename: counter.go
change_type: ModificationType.ADD
diff: @@ -0,0 +1,13 @@
+// Copyright Tharsis Labs Ltd.(Evmos)
+// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
+
+package contracts
+
+import (
+	contractutils "github.com/evmos/evmos/v18/contracts/utils"
+	evmtypes "github.com/evmos/evmos/v18/x/evm/types"
+)
+
+func LoadCounterContract() (evmtypes.CompiledContract, error) {
+	return contractutils.LoadContractFromJSONFile("Counter.json")
+}

programming_language: Go
filename: errors.go
change_type: ModificationType.MODIFY
diff: @@ -7,4 +7,6 @@ const (
 	ErrDifferentFromOrigin = "tx origin address %s does not match the from address %s"
 	// ErrDifferentFunderOrigin is raised when the tx origin address is not the same as the vesting transaction funder.
 	ErrDifferentFunderOrigin = "tx origin address %s does not match the funder address %s"
+	// ErrInvalidDestination is raised when the destination address is not an EOA or the contract calling the precompile.
+	ErrInvalidDestination = "invalid destination address %s. Should be an EOA or the contract calling the precompile"
 )

programming_language: Go
filename: events.go
change_type: ModificationType.MODIFY
diff: @@ -90,10 +90,6 @@ func (p Precompile) EmitCreateClawbackVestingAccountEvent(
 		return err
 	}
 
-	if err != nil {
-		return err
-	}
-
 	// Create the event
 	stateDB.AddLog(&ethtypes.Log{
 		Address:     p.Address(),

programming_language: Go
filename: integration_test.go
change_type: ModificationType.MODIFY
diff: @@ -17,6 +17,7 @@ import (
 	"github.com/evmos/evmos/v18/precompiles/vesting"
 	evmosutil "github.com/evmos/evmos/v18/testutil"
 	testutiltx "github.com/evmos/evmos/v18/testutil/tx"
+	"github.com/evmos/evmos/v18/utils"
 	vestingtypes "github.com/evmos/evmos/v18/x/vesting/types"
 
 	//nolint:revive // dot imports are fine for Ginkgo
@@ -55,6 +56,8 @@ var (
 	differentAddr = testutiltx.GenerateAddress()
 	// vestingAddr is a new address that is used to test the vesting extension.
 	vestingAddr = testutiltx.GenerateAddress()
+	// gasPrice to be used on tests txs and calculate the fees
+	gasPrice = math.NewInt(1e9)
 )
 
 var _ = Describe("Interacting with the vesting extension", func() {
@@ -228,19 +231,22 @@ var _ = Describe("Interacting with the vesting extension", func() {
 	})
 
 	Context("to fund a clawback vesting account", func() {
+
 		for _, callType := range callTypes {
 			callType := callType
 
-			BeforeEach(func() {
-				if callType.directCall == false {
+			It(fmt.Sprintf("should fund the vesting when defining only lockup (%s)", callType.name), func() {
+				if !callType.directCall {
+					// create authorization to allow contract to spend the funder's (s.address) balance
+					// when funding a vesting account
 					err = vesting.CreateGenericAuthz(s.ctx, s.app.AuthzKeeper, contractAddr, s.address, vesting.FundVestingAccountMsgURL)
 					Expect(err).ToNot(HaveOccurred(), "error while creating the generic authorization: %v", err)
 				}
-			})
-
-			It(fmt.Sprintf("should fund the vesting when defining only lockup (%s)", callType.name), func() {
 				s.CreateTestClawbackVestingAccount(s.address, toAddr)
-				createClawbackArgs := s.BuildCallArgs(callType, contractAddr).
+
+				vestAccInitialBal := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+
+				fundVestingAccArgs := s.BuildCallArgs(callType, contractAddr).
 					WithMethodName(vesting.FundVestingAccountMethod).
 					WithArgs(
 						s.address,
@@ -253,19 +259,200 @@ var _ = Describe("Interacting with the vesting extension", func() {
 				fundClawbackVestingCheck := passCheck.
 					WithExpEvents(vesting.EventTypeFundVestingAccount)
 
-				_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, createClawbackArgs, fundClawbackVestingCheck)
+				_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, fundVestingAccArgs, fundClawbackVestingCheck)
+				Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+
+				// Check the vesting account
+				//
+				// NOTE: The vesting account is created with the lockup periods only, since the vesting periods are empty.
+				// The vesting periods are defaulted to instant vesting, i.e. period length = 0.
+				s.ExpectVestingAccount(toAddr, defaultPeriods, instantPeriods)
+
+				vestCoinsAmt := math.NewIntFromBigInt(defaultPeriods[0].Amount[0].Amount)
+				vestAccFinalBal := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+				Expect(vestAccFinalBal.Amount).To(Equal(vestAccInitialBal.Amount.Add(vestCoinsAmt)))
+			})
+
+			It(fmt.Sprintf("should fund the vesting account from a smart contract when defining only lockup (%s)", callType.name), func() {
+				if callType.directCall {
+					Skip("this should only be run for smart contract calls")
+				}
+				s.CreateTestClawbackVestingAccount(contractAddr, toAddr)
+				// send some funds to the smart contract
+				// authorization to be able to fund from the smart contract is already in the setup
+				err = evmosutil.FundAccount(s.ctx, s.app.BankKeeper, contractAddr.Bytes(), sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(100))))
+				Expect(err).ToNot(HaveOccurred(), "error while funding the contract: %v", err)
+
+				txSenderInitialBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+				vestAccInitialBal := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+
+				// Build and execute the tx to fund the vesting account from a smart contract
+				fundVestingAccArgs := s.BuildCallArgs(callType, contractAddr).
+					WithMethodName(vesting.FundVestingAccountMethod).
+					WithArgs(
+						contractAddr,
+						toAddr,
+						uint64(time.Now().Unix()),
+						defaultPeriods,
+						emptyPeriods,
+					).
+					WithGasPrice(gasPrice.BigInt())
+
+				fundClawbackVestingCheck := passCheck.
+					WithExpEvents(vesting.EventTypeFundVestingAccount)
+
+				res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, fundVestingAccArgs, fundClawbackVestingCheck)
 				Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+				fees := gasPrice.MulRaw(res.GasUsed)
 
 				// Check the vesting account
 				//
 				// NOTE: The vesting account is created with the lockup periods only, since the vesting periods are empty.
 				// The vesting periods are defaulted to instant vesting, i.e. period length = 0.
 				s.ExpectVestingAccount(toAddr, defaultPeriods, instantPeriods)
+
+				// check that tx signer's balance is reduced by the fees paid
+				txSenderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+				Expect(txSenderFinalBal.Amount).To(Equal(txSenderInitialBal.Amount.Sub(fees)))
+
+				// check the contract's balance was deducted to fund the vesting account
+				contractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+				Expect(contractFinalBal.Amount).To(Equal(sdk.ZeroInt()))
+
+				vestCoinsAmt := math.NewIntFromBigInt(defaultPeriods[0].Amount[0].Amount)
+				vestAccFinalBal := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+				Expect(vestAccFinalBal.Amount).To(Equal(vestAccInitialBal.Amount.Add(vestCoinsAmt)))
+			})
+
+			It(fmt.Sprintf("contract that calls funder - should NOT fund the vesting account with a smart contract different than the contract that calls the precompile (%s)", callType.name), func() {
+				if callType.directCall {
+					Skip("this should only be run for smart contract calls")
+				}
+				counterContract, err := contracts.LoadCounterContract()
+				Expect(err).ToNot(HaveOccurred())
+
+				funderContractAddr, err := s.DeployContract(counterContract)
+				Expect(err).ToNot(HaveOccurred(), "error while deploying the smart contract: %v", err)
+
+				s.CreateTestClawbackVestingAccount(funderContractAddr, toAddr)
+				// send some funds to the smart contract
+				// authorization to be able to fund from the smart contract is already in the setup
+				funderContractInitialAmt := math.NewInt(200)
+				err = evmosutil.FundAccount(s.ctx, s.app.BankKeeper, funderContractAddr.Bytes(), sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, funderContractInitialAmt)))
+				Expect(err).ToNot(HaveOccurred(), "error while funding the contract: %v", err)
+
+				// create authorization for tx sender to use funder's balance to fund a vesting account
+				err = vesting.CreateGenericAuthz(s.ctx, s.app.AuthzKeeper, s.address, funderContractAddr, vesting.FundVestingAccountMsgURL)
+				Expect(err).ToNot(HaveOccurred(), "error while creating the generic authorization: %v", err)
+
+				txSenderInitialBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+
+				// Build and execute the tx to fund the vesting account from a smart contract
+				fundVestingAccArgs := s.BuildCallArgs(callType, contractAddr).
+					WithMethodName(vesting.FundVestingAccountMethod).
+					WithArgs(
+						funderContractAddr,
+						toAddr,
+						uint64(time.Now().Unix()),
+						defaultPeriods,
+						emptyPeriods,
+					)
+				_, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, fundVestingAccArgs, execRevertedCheck)
+				Expect(err).To(HaveOccurred())
+
+				// check that tx signer's balance is reduced by the fees paid
+				txSenderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+				Expect(txSenderFinalBal.Amount.LTE(txSenderInitialBal.Amount)).To(BeTrue())
+
+				// the balance of the contract that calls the precompile should remain 0
+				contractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+				Expect(contractFinalBal.Amount).To(Equal(sdk.ZeroInt()))
+
+				// the balance of the funder contract should remain unchanged
+				funderContractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, funderContractAddr.Bytes(), s.bondDenom)
+				Expect(funderContractFinalBal.Amount).To(Equal(funderContractInitialAmt))
+			})
+
+			It(fmt.Sprintf("fund using a third party EOA - should NOT fund the vesting account even if authorized (%s)", callType.name), func() {
+				if callType.directCall {
+					Skip("this should only be run for smart contract calls")
+				}
+
+				// send some funds to the funder, a third party EOA
+				funderAccAddr, _ := testutiltx.NewAccAddressAndKey()
+				funderHexAddr := common.BytesToAddress(funderAccAddr)
+				initialFunderBalance := math.NewInt(200)
+				err = evmosutil.FundAccount(s.ctx, s.app.BankKeeper, funderAccAddr, sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, initialFunderBalance)))
+				Expect(err).ToNot(HaveOccurred(), "error while funding the third party EOA: %v", err)
+
+				// create authorization for tx sender to use funder's balance to fund a vesting account
+				err = vesting.CreateGenericAuthz(s.ctx, s.app.AuthzKeeper, s.address, funderHexAddr, vesting.FundVestingAccountMsgURL)
+				Expect(err).ToNot(HaveOccurred(), "error while creating the generic authorization: %v", err)
+
+				// create clawback vesting account with the corresponding funder
+				s.CreateTestClawbackVestingAccount(funderHexAddr, toAddr)
+
+				txSenderInitialBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+
+				// Build and execute the tx to fund the vesting account from a third party EOA
+				fundVestingAccArgs := s.BuildCallArgs(callType, contractAddr).
+					WithMethodName(vesting.FundVestingAccountMethod).
+					WithArgs(
+						funderHexAddr,
+						toAddr,
+						uint64(time.Now().Unix()),
+						defaultPeriods,
+						emptyPeriods,
+					).
+					WithGasPrice(gasPrice.BigInt())
+
+				_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, fundVestingAccArgs, execRevertedCheck)
+				Expect(err).To(HaveOccurred())
+
+				// check that tx signer's balance is reduced by the fees paid
+				txSenderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+				Expect(txSenderFinalBal.Amount.LTE(txSenderInitialBal.Amount)).To(BeTrue())
+
+				// check the funders's balance remains unchanged
+				funderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, funderAccAddr, s.bondDenom)
+				Expect(funderFinalBal.Amount).To(Equal(initialFunderBalance))
+			})
+
+			It(fmt.Sprintf("should NOT fund the vesting with tx origin funds when calling the precompile from a smart contract and WITHOUT authorization (%s)", callType.name), func() {
+				// when calling from a smart contract
+				// the funder (s.address) needs to authorize
+				// for the smart contract to use its funds
+				if callType.directCall {
+					Skip("this should only be run for smart contract calls")
+				}
+				s.CreateTestClawbackVestingAccount(s.address, toAddr)
+				fundVestingAccArgs := s.BuildCallArgs(callType, contractAddr).
+					WithMethodName(vesting.FundVestingAccountMethod).
+					WithArgs(
+						s.address,
+						toAddr,
+						uint64(time.Now().Unix()),
+						emptyPeriods,
+						defaultPeriods,
+					)
+
+				_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, fundVestingAccArgs, execRevertedCheck)
+				Expect(err).To(HaveOccurred(), "error while calling the contract: %v", err)
 			})
 
 			It(fmt.Sprintf("should fund the vesting when defining only vesting (%s)", callType.name), func() {
+				// when calling from a smart contract
+				// the funder (s.address) needs to authorize
+				// for the smart contract to use its funds
+				if !callType.directCall {
+					// create authorization to allow contract to spend the funder's (s.address) balance
+					// when funding a vesting account
+					err = vesting.CreateGenericAuthz(s.ctx, s.app.AuthzKeeper, contractAddr, s.address, vesting.FundVestingAccountMsgURL)
+					Expect(err).ToNot(HaveOccurred(), "error while creating the generic authorization: %v", err)
+				}
+
 				s.CreateTestClawbackVestingAccount(s.address, toAddr)
-				createClawbackArgs := s.BuildCallArgs(callType, contractAddr).
+				fundVestingAccArgs := s.BuildCallArgs(callType, contractAddr).
 					WithMethodName(vesting.FundVestingAccountMethod).
 					WithArgs(
 						s.address,
@@ -278,7 +465,7 @@ var _ = Describe("Interacting with the vesting extension", func() {
 				fundClawbackVestingCheck := passCheck.
 					WithExpEvents(vesting.EventTypeFundVestingAccount)
 
-				_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, createClawbackArgs, fundClawbackVestingCheck)
+				_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, fundVestingAccArgs, fundClawbackVestingCheck)
 				Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
 
 				// Check the vesting account
@@ -288,8 +475,190 @@ var _ = Describe("Interacting with the vesting extension", func() {
 				s.ExpectVestingAccount(toAddr, instantPeriods, defaultPeriods)
 			})
 
+			Context("Table-driven tests for Withdraw Delegator Rewards", func() {
+				// testCase is a struct used for cases of contracts calls that have some operation
+				// performed before and/or after the precompile call
+				type testCase struct {
+					transferTo *common.Address
+					before     bool
+					after      bool
+				}
+
+				var (
+					args                   contracts.CallArgs
+					funderInitialBal       sdk.Coin
+					vestingAccInitialBal   sdk.Coin
+					contractInitialBalance = math.NewInt(100)
+				)
+
+				BeforeEach(func() {
+					args = s.BuildCallArgs(callType, contractAddr).
+						WithMethodName("fundVestingAccountAndTransfer").
+						WithGasPrice(gasPrice.BigInt())
+
+					// send some funds to the contract
+					err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, contractAddr.Bytes(), contractInitialBalance.Int64())
+					Expect(err).To(BeNil())
+
+					s.CreateTestClawbackVestingAccount(s.address, toAddr)
+
+					funderInitialBal = s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+					vestingAccInitialBal = s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+
+					// create authorization to allow contract to spend the funder's (s.address) balance
+					// when funding a vesting account
+					err = vesting.CreateGenericAuthz(s.ctx, s.app.AuthzKeeper, contractAddr, s.address, vesting.FundVestingAccountMsgURL)
+					Expect(err).ToNot(HaveOccurred(), "error while creating the generic authorization: %v", err)
+				})
+
+				DescribeTable(fmt.Sprintf("should fund the vesting account from tx origin when defining only vesting (%s)", callType.name), func(tc testCase) {
+					if callType.directCall {
+						Skip("this should only be run for smart contract calls")
+					}
+					// if not specified, default the transferTo to the funder address
+					if tc.transferTo == nil {
+						tc.transferTo = &s.address
+					}
+					fundVestingAccArgs := args.
+						WithArgs(
+							s.address,
+							toAddr,
+							*tc.transferTo,
+							uint64(time.Now().Unix()),
+							emptyPeriods,
+							defaultPeriods,
+							tc.before, tc.after, // transfer funds to the funder according to test case
+						).
+						WithGasPrice(gasPrice.BigInt())
+
+					fundClawbackVestingCheck := passCheck.
+						WithExpEvents(vesting.EventTypeFundVestingAccount)
+
+					res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, fundVestingAccArgs, fundClawbackVestingCheck)
+					Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+
+					fees := gasPrice.MulRaw(res.GasUsed)
+
+					transferredToAmt := math.ZeroInt()
+					for _, transferred := range []bool{tc.before, tc.after} {
+						if transferred {
+							transferredToAmt = transferredToAmt.AddRaw(15)
+						}
+					}
+					// Check the vesting account
+					//
+					// NOTE: The vesting account is created with the vesting periods only, since the lockup periods are empty.
+					// The lockup periods are defaulted to instant unlocking, i.e. period length = 0.
+					s.ExpectVestingAccount(toAddr, instantPeriods, defaultPeriods)
+
+					// check the contract's balance was deducted to fund the vesting account
+					contractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+					Expect(contractFinalBal.Amount).To(Equal(contractInitialBalance.Sub(transferredToAmt)))
+
+					// check that the vesting account received the funds
+					vestCoinsAmt := math.NewIntFromBigInt(defaultPeriods[0].Amount[0].Amount)
+					vestAccFinalBal := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					expVestAccFinalBal := vestingAccInitialBal.Amount.Add(vestCoinsAmt)
+					if *tc.transferTo == toAddr {
+						expVestAccFinalBal = expVestAccFinalBal.Add(transferredToAmt)
+					}
+
+					Expect(vestAccFinalBal.Amount).To(Equal(expVestAccFinalBal))
+
+					// check that funder balance is reduced by the fees paid, the amt to fund the vesting account,
+					// but also got the funds sent from the contract (when corresponds)
+					funderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+
+					expFunderFinalBal := funderInitialBal.Amount.Sub(fees).Sub(vestCoinsAmt)
+					if *tc.transferTo == s.address {
+						expFunderFinalBal = expFunderFinalBal.Add(transferredToAmt)
+					}
+
+					Expect(funderFinalBal.Amount).To(Equal(expFunderFinalBal))
+				},
+					Entry("funder balance change before & after precompile call", testCase{
+						before: true,
+						after:  true,
+					}),
+					Entry("funder balance change before precompile call", testCase{
+						before: true,
+						after:  false,
+					}),
+					Entry("funder balance change after precompile call", testCase{
+						before: false,
+						after:  true,
+					}),
+					Entry("vesting acc balance change before & after precompile call", testCase{
+						transferTo: &toAddr,
+						before:     true,
+						after:      true,
+					}),
+					Entry("vesting acc balance change before precompile call", testCase{
+						transferTo: &toAddr,
+						before:     true,
+						after:      false,
+					}),
+					Entry("vesting acc balance change after precompile call", testCase{
+						transferTo: &toAddr,
+						before:     false,
+						after:      true,
+					}),
+				)
+			})
+
+			It(fmt.Sprintf("should fund the vesting account from a smart contract when defining only vesting (%s)", callType.name), func() {
+				if callType.directCall {
+					Skip("this should only be run for smart contract calls")
+				}
+				s.CreateTestClawbackVestingAccount(contractAddr, toAddr)
+				// send some funds to the smart contract
+				// authorization is already created in the test setup
+				err = evmosutil.FundAccount(s.ctx, s.app.BankKeeper, contractAddr.Bytes(), sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(100))))
+				Expect(err).ToNot(HaveOccurred(), "error while funding the contract: %v", err)
+
+				txSenderInitialBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+
+				// Build and execute the tx to fund the vesting account from a smart contract
+				createClawbackArgs := s.BuildCallArgs(callType, contractAddr).
+					WithMethodName(vesting.FundVestingAccountMethod).
+					WithArgs(
+						contractAddr,
+						toAddr,
+						uint64(time.Now().Unix()),
+						emptyPeriods,
+						defaultPeriods,
+					).
+					WithGasPrice(gasPrice.BigInt())
+
+				fundClawbackVestingCheck := passCheck.
+					WithExpEvents(vesting.EventTypeFundVestingAccount)
+
+				res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, createClawbackArgs, fundClawbackVestingCheck)
+				Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+				fees := gasPrice.MulRaw(res.GasUsed)
+
+				// Check the vesting account
+				s.ExpectVestingAccount(toAddr, instantPeriods, defaultPeriods)
+
+				// check that tx signer's balance is reduced by the fees paid
+				txSenderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+				Expect(txSenderFinalBal.Amount).To(Equal(txSenderInitialBal.Amount.Sub(fees)))
+
+				// check the contract's balance was deducted to fund the vesting account
+				contractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+				Expect(contractFinalBal.Amount).To(Equal(sdk.ZeroInt()))
+			})
+
 			It(fmt.Sprintf("should fund the vesting when defining both lockup and vesting (%s)", callType.name), func() {
 				s.CreateTestClawbackVestingAccount(s.address, toAddr)
+				// funder is an EOA (s.address)
+				// if calling funding via contract call,
+				// need auth from funder addr (s.address)
+				// to the contract address
+				if !callType.directCall {
+					err = vesting.CreateGenericAuthz(s.ctx, s.app.AuthzKeeper, contractAddr, s.address, vesting.FundVestingAccountMsgURL)
+					Expect(err).ToNot(HaveOccurred(), "error while creating the generic authorization: %v", err)
+				}
 				createClawbackArgs := s.BuildCallArgs(callType, contractAddr).
 					WithMethodName(vesting.FundVestingAccountMethod).
 					WithArgs(
@@ -310,6 +679,48 @@ var _ = Describe("Interacting with the vesting extension", func() {
 				s.ExpectVestingAccount(toAddr, defaultPeriods, defaultPeriods)
 			})
 
+			It(fmt.Sprintf("should fund the vesting account from a smart contract when defining both lockup and vesting  (%s)", callType.name), func() {
+				if callType.directCall {
+					Skip("this should only be run for smart contract calls")
+				}
+				s.CreateTestClawbackVestingAccount(contractAddr, toAddr)
+				// send some funds to the smart contract
+				err = evmosutil.FundAccount(s.ctx, s.app.BankKeeper, contractAddr.Bytes(), sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(100))))
+				Expect(err).ToNot(HaveOccurred(), "error while funding the contract: %v", err)
+
+				txSenderInitialBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+
+				// Build and execute the tx to fund the vesting account from a smart contract
+				createClawbackArgs := s.BuildCallArgs(callType, contractAddr).
+					WithMethodName(vesting.FundVestingAccountMethod).
+					WithArgs(
+						contractAddr,
+						toAddr,
+						uint64(time.Now().Unix()),
+						defaultPeriods,
+						defaultPeriods,
+					).
+					WithGasPrice(gasPrice.BigInt())
+
+				fundClawbackVestingCheck := passCheck.
+					WithExpEvents(vesting.EventTypeFundVestingAccount)
+
+				res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, createClawbackArgs, fundClawbackVestingCheck)
+				Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+				fees := gasPrice.MulRaw(res.GasUsed)
+
+				// Check the vesting account
+				s.ExpectVestingAccount(toAddr, defaultPeriods, defaultPeriods)
+
+				// check that tx signer's balance is reduced by the fees paid
+				txSenderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+				Expect(txSenderFinalBal.Amount).To(Equal(txSenderInitialBal.Amount.Sub(fees)))
+
+				// check the contract's balance was deducted to fund the vesting account
+				contractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+				Expect(contractFinalBal.Amount).To(Equal(sdk.ZeroInt()))
+			})
+
 			It(fmt.Sprintf("should not fund the vesting when defining different total coins for lockup and vesting (%s)", callType.name), func() {
 				s.CreateTestClawbackVestingAccount(s.address, toAddr)
 
@@ -546,6 +957,8 @@ var _ = Describe("Interacting with the vesting extension", func() {
 	})
 
 	Context("to claw back from a vesting account", func() {
+		var expClawbackAmt = math.NewInt(1000)
+
 		BeforeEach(func() {
 			s.CreateTestClawbackVestingAccount(s.address, toAddr)
 			s.FundTestClawbackVestingAccount()
@@ -554,132 +967,504 @@ var _ = Describe("Interacting with the vesting extension", func() {
 		for _, callType := range callTypes {
 			callType := callType
 
-			BeforeEach(func() {
-				if callType.directCall == false {
-					err = vesting.CreateGenericAuthz(s.ctx, s.app.AuthzKeeper, contractAddr, s.address, vesting.ClawbackMsgURL)
-					Expect(err).ToNot(HaveOccurred(), "error while creating the generic authorization: %v", err)
-				}
-			})
-
-			It(fmt.Sprintf("should claw back from the vesting when sending as the funder (%s)", callType.name), func() {
-				balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
-				Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
-
-				clawbackArgs := s.BuildCallArgs(callType, contractAddr).
-					WithMethodName(vesting.ClawbackMethod).
-					WithArgs(
-						s.address,
-						toAddr,
-						differentAddr,
-					)
-
-				clawbackCheck := passCheck.
-					WithExpEvents(vesting.EventTypeClawback)
-
-				_, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
-				Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+			Context("without authorization", func() {
+				It(fmt.Sprintf("should NOT claw back from the vesting when sending tx from the funder (%s)", callType.name), func() {
+					if callType.directCall {
+						Skip("this should only be run for smart contract calls")
+					}
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName(vesting.ClawbackMethod).
+						WithArgs(
+							s.address,
+							toAddr,
+							differentAddr,
+						)
 
-				var co vesting.ClawbackOutput
-				err = s.precompile.UnpackIntoInterface(&co, vesting.ClawbackMethod, ethRes.Ret)
-				Expect(err).ToNot(HaveOccurred(), "error while unpacking the clawback output: %v", err)
-				Expect(co.Coins).To(Equal(balances), "expected different clawback amount")
+					_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, execRevertedCheck)
+					Expect(err).To(HaveOccurred(), "error while calling the contract: %v", err)
 
-				balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
-				Expect(balancePost.Amount.Int64()).To(Equal(int64(100)), "expected only initial balance after clawback")
-				balanceReceiver := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom)
-				Expect(balanceReceiver.Amount).To(Equal(math.NewInt(1000)), "expected receiver to show different balance after clawback")
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost.Amount).To(Equal(balancePre.Amount))
+					balanceReceiver := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom)
+					Expect(balanceReceiver.Amount).To(Equal(math.ZeroInt()))
+				})
 			})
 
-			It(fmt.Sprintf("should return an error when not sending as the funder (%s)", callType.name), func() {
-				// create and fund new account
-				differentAddr, differentPriv := testutiltx.NewAddrKey()
-				err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, differentAddr.Bytes(), 1e18)
-				Expect(err).ToNot(HaveOccurred(), "error while funding the account: %v", err)
-
-				balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
-				Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
-
-				clawbackArgs := s.BuildCallArgs(callType, contractAddr).
-					WithMethodName(vesting.ClawbackMethod).
-					WithPrivKey(differentPriv).
-					WithArgs(
-						s.address,
-						toAddr,
-						differentAddr,
-					)
-
-				clawbackCheck := execRevertedCheck
-				if callType.directCall {
-					clawbackCheck = failCheck.
-						WithErrContains(fmt.Sprintf(
-							"tx origin address %s does not match the funder address %s",
-							differentAddr, s.address,
-						))
-				}
-
-				_, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
-				Expect(err).To(HaveOccurred(), "error while calling the contract: %v", err)
-				if callType.directCall {
-					Expect(err.Error()).To(ContainSubstring("does not match the funder address"))
-				}
-				balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
-				Expect(balancePost).To(Equal(balancePre), "expected balance not to have changed")
-			})
-
-			It(fmt.Sprintf("should return an error when the vesting does not exist (%s)", callType.name), func() {
-				// fund the new account
-				err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, differentAddr.Bytes(), 1e18)
-				Expect(err).ToNot(HaveOccurred(), "error while funding the account: %v", err)
+			Context("with authorization", func() {
+				BeforeEach(func() {
+					if callType.directCall == false {
+						err = vesting.CreateGenericAuthz(s.ctx, s.app.AuthzKeeper, contractAddr, s.address, vesting.ClawbackMsgURL)
+						Expect(err).ToNot(HaveOccurred(), "error while creating the generic authorization: %v", err)
+					}
+				})
+
+				It(fmt.Sprintf("should claw back from the vesting when sending as the funder (%s)", callType.name), func() {
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName(vesting.ClawbackMethod).
+						WithArgs(
+							s.address,
+							toAddr,
+							differentAddr,
+						)
 
-				clawbackArgs := s.BuildCallArgs(callType, contractAddr).
-					WithMethodName(vesting.ClawbackMethod).
-					WithArgs(
-						s.address,
-						differentAddr,
-						s.address,
+					clawbackCheck := passCheck.
+						WithExpEvents(vesting.EventTypeClawback)
+
+					_, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
+					Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+
+					var co vesting.ClawbackOutput
+					err = s.precompile.UnpackIntoInterface(&co, vesting.ClawbackMethod, ethRes.Ret)
+					Expect(err).ToNot(HaveOccurred(), "error while unpacking the clawback output: %v", err)
+					Expect(co.Coins).To(Equal(balances), "expected different clawback amount")
+
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost.Amount.Int64()).To(Equal(int64(100)), "expected only initial balance after clawback")
+					balanceReceiver := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom)
+					Expect(balanceReceiver.Amount).To(Equal(math.NewInt(1000)), "expected receiver to show different balance after clawback")
+				})
+
+				Context("table tests for clawback with state changes", func() {
+					type testCase struct {
+						dest       common.Address
+						transferTo *common.Address
+						before     bool
+						after      bool
+					}
+					DescribeTable(fmt.Sprintf("smart contract as funder - contract with state changes on destination address - should claw back from the vesting when sending as the funder (%s)", callType.name), func(tc testCase) {
+						if callType.directCall {
+							Skip("this should only be run for smart contract calls")
+						}
+						if tc.transferTo == nil {
+							tc.transferTo = &tc.dest
+						}
+						// change the vesting account funder to be the contract
+						_, err := s.app.VestingKeeper.UpdateVestingFunder(s.ctx, &vestingtypes.MsgUpdateVestingFunder{
+							FunderAddress:    sdk.AccAddress(s.address.Bytes()).String(),
+							NewFunderAddress: sdk.AccAddress(contractAddr.Bytes()).String(),
+							VestingAddress:   sdk.AccAddress(toAddr.Bytes()).String(),
+						})
+						Expect(err).ToNot(HaveOccurred())
+
+						// fund the contract to make internal transfers
+						contractInitialBalance := math.NewInt(100)
+						err = evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, contractAddr.Bytes(), contractInitialBalance.Int64())
+						Expect(err).ToNot(HaveOccurred(), "error while funding the contract: %v", err)
+
+						vestAccInitialBal := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+						Expect(vestAccInitialBal.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+						clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+							WithMethodName("clawbackWithTransfer").
+							WithArgs(
+								contractAddr,
+								toAddr,
+								tc.dest,
+								*tc.transferTo,
+								tc.before,
+								tc.after,
+							)
+
+						clawbackCheck := passCheck.
+							WithExpEvents(vesting.EventTypeClawback)
+
+						_, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
+						Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+
+						var co vesting.ClawbackOutput
+						err = s.precompile.UnpackIntoInterface(&co, vesting.ClawbackMethod, ethRes.Ret)
+						Expect(err).ToNot(HaveOccurred(), "error while unpacking the clawback output: %v", err)
+						Expect(co.Coins).To(Equal(balances), "expected different clawback amount")
+
+						contractTransferredAmt := math.ZeroInt()
+						for _, transferred := range []bool{tc.before, tc.after} {
+							if transferred {
+								contractTransferredAmt = contractTransferredAmt.AddRaw(15)
+							}
+						}
+
+						vestAccFinalBalance := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+						expVestAccFinalBal := vestAccInitialBal.Amount.Sub(expClawbackAmt)
+						if *tc.transferTo == toAddr {
+							expVestAccFinalBal = expVestAccFinalBal.Add(contractTransferredAmt)
+						}
+						Expect(vestAccFinalBalance.Amount).To(Equal(expVestAccFinalBal), "expected only initial balance after clawback")
+
+						// contract transfers balances when it is not the destination
+						if tc.dest == contractAddr {
+							contractFinalBalance := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+							Expect(contractFinalBalance.Amount).To(Equal(contractInitialBalance.Add(expClawbackAmt)))
+							return
+						}
+
+						balanceDest := s.app.BankKeeper.GetBalance(s.ctx, tc.dest.Bytes(), s.bondDenom)
+						expBalDest := expClawbackAmt
+						if *tc.transferTo == tc.dest {
+							expBalDest = expBalDest.Add(contractTransferredAmt)
+						}
+						Expect(balanceDest.Amount).To(Equal(expBalDest), "expected receiver to show different balance after clawback")
+
+						contractFinalBalance := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+						Expect(contractFinalBalance.Amount).To(Equal(contractInitialBalance.Sub(contractTransferredAmt)))
+					},
+						Entry("funder is the destination address - state changes before & after precompile call", testCase{
+							dest:   contractAddr,
+							before: true,
+							after:  true,
+						}),
+						Entry("funder is the destination address - state changes before precompile call", testCase{
+							dest:   contractAddr,
+							before: true,
+							after:  false,
+						}),
+						Entry("funder is the destination address - state changes after precompile call", testCase{
+							dest:   contractAddr,
+							before: false,
+							after:  true,
+						}),
+						Entry("another address is the destination address - state changes before & after precompile", testCase{
+							dest:   differentAddr,
+							before: true,
+							after:  true,
+						}),
+						Entry("another address is the destination address - state changes before precompile", testCase{
+							dest:   differentAddr,
+							before: true,
+							after:  false,
+						}),
+						Entry("another address is the destination address - state changes after precompile", testCase{
+							dest:   differentAddr,
+							before: false,
+							after:  true,
+						}),
+						Entry("another address is the destination address - transfer to vest acc before & after precompile", testCase{
+							dest:       differentAddr,
+							transferTo: &toAddr,
+							before:     true,
+							after:      true,
+						}),
+						Entry("another address is the destination address - transfer to vest acc before precompile", testCase{
+							dest:       differentAddr,
+							transferTo: &toAddr,
+							before:     true,
+							after:      false,
+						}),
+						Entry("another address is the destination address - transfer to vest acc after precompile", testCase{
+							dest:       differentAddr,
+							transferTo: &toAddr,
+							before:     false,
+							after:      true,
+						}),
 					)
+				})
+
+				It(fmt.Sprintf("should claw back from the vesting when sending as the funder with the caller smart contract as destination for the clawed back funds (%s)", callType.name), func() {
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					// check the contract's (destination) intial balance. Should be 0
+					contractInitialBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+					Expect(contractInitialBal.Amount).To(Equal(sdk.ZeroInt()))
+
+					// get tx sender initial balance
+					txSenderInitialBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName(vesting.ClawbackMethod).
+						WithArgs(
+							s.address,
+							toAddr,
+							contractAddr,
+						).
+						WithGasPrice(gasPrice.BigInt())
+
+					clawbackCheck := passCheck.
+						WithExpEvents(vesting.EventTypeClawback)
+
+					res, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
+					Expect(err).ToNot(HaveOccurred(), "error while calling the contract: %v", err)
+
+					fees := gasPrice.MulRaw(res.GasUsed)
+
+					var co vesting.ClawbackOutput
+					err = s.precompile.UnpackIntoInterface(&co, vesting.ClawbackMethod, ethRes.Ret)
+					Expect(err).ToNot(HaveOccurred(), "error while unpacking the clawback output: %v", err)
+					Expect(co.Coins).To(Equal(balances), "expected different clawback amount")
+
+					// check clawback account balance
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost.Amount.Int64()).To(Equal(int64(100)), "expected only initial balance after clawback")
+
+					// check that tx signer's balance is reduced by the fees paid
+					txSenderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+					Expect(txSenderFinalBal.Amount).To(Equal(txSenderInitialBal.Amount.Sub(fees)))
+
+					// check contract's final balance (clawback destination)
+					contractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+					Expect(contractFinalBal.Amount).To(Equal(math.NewInt(1000)), "expected receiver to show different balance after clawback")
+				})
+
+				It(fmt.Sprintf("clawback with revert after precompile call but before changing contract state - should NOT claw back and revert all balances to initial values (%s)", callType.name), func() {
+					if callType.directCall {
+						Skip("this should only be run for smart contract calls")
+					}
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName("clawbackWithRevert").
+						WithArgs(
+							s.address,
+							toAddr,
+							differentAddr,
+							true,
+						)
 
-				clawbackCheck := execRevertedCheck
-				// FIXME: error messages in fail check now work differently!
-				if callType.directCall {
-					clawbackCheck = failCheck.
-						WithErrContains(vestingtypes.ErrNotSubjectToClawback.Error())
-				}
-
-				_, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
-				Expect(err).To(HaveOccurred(), "error while calling the contract: %v", err)
-				if callType.directCall {
-					Expect(err.Error()).To(ContainSubstring("%s: %s", sdk.AccAddress(differentAddr.Bytes()), vestingtypes.ErrNotSubjectToClawback.Error()))
-				}
-			})
+					_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, execRevertedCheck)
+					Expect(err).To(HaveOccurred())
+
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost.Amount).To(Equal(balancePre.Amount), "expected no balance change")
+					balanceReceiver := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom)
+					Expect(balanceReceiver.Amount).To(Equal(math.ZeroInt()))
+				})
+
+				It(fmt.Sprintf("clawback with revert after precompile after changing contract state - should NOT claw back and revert all balances to initial values (%s)", callType.name), func() {
+					if callType.directCall {
+						Skip("this should only be run for smart contract calls")
+					}
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName("clawbackWithRevert").
+						WithArgs(
+							s.address,
+							toAddr,
+							differentAddr,
+							false,
+						)
 
-			It(fmt.Sprintf("should succeed and return empty Coins when all tokens are vested (%s)", callType.name), func() {
-				// commit block with time so that vesting has ended
-				ctx, err := evmosutil.CommitAndCreateNewCtx(s.ctx, s.app, time.Hour*24, nil)
-				Expect(err).ToNot(HaveOccurred(), "error while committing block: %v", err)
-				s.ctx = ctx
+					_, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, execRevertedCheck)
+					Expect(err).To(HaveOccurred())
+
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost.Amount).To(Equal(balancePre.Amount), "expected no balance change")
+					balanceReceiver := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom)
+					Expect(balanceReceiver.Amount).To(Equal(math.ZeroInt()))
+				})
+
+				It(fmt.Sprintf("another contract as destination - should clawback from the vesting when sending as the funder with another smart contract as destination for the clawed back funds (%s)", callType.name), func() {
+					counterContract, err := contracts.LoadCounterContract()
+					Expect(err).ToNot(HaveOccurred())
+
+					destContractAddr, err := s.DeployContract(counterContract)
+					Expect(err).ToNot(HaveOccurred(), "error while deploying the smart contract: %v", err)
+
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					// check the contract's (destination) intial balance. Should be 0
+					destContractInitialBal := s.app.BankKeeper.GetBalance(s.ctx, destContractAddr.Bytes(), s.bondDenom)
+					Expect(destContractInitialBal.Amount).To(Equal(sdk.ZeroInt()))
+
+					// get tx sender initial balance
+					txSenderInitialBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+
+					clawbackCheck := passCheck.
+						WithExpEvents(vesting.EventTypeClawback)
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName(vesting.ClawbackMethod).
+						WithArgs(
+							s.address,
+							toAddr,
+							destContractAddr,
+						).
+						WithGasPrice(gasPrice.BigInt())
+
+					res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
+					Expect(err).NotTo(HaveOccurred())
+					fees := gasPrice.MulRaw(res.GasUsed)
+
+					// check clawback account balance
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost.Amount).To(Equal(balancePre.Amount.Sub(expClawbackAmt)))
+
+					// check that tx signer's balance is reduced by the fees paid
+					txSenderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+					Expect(txSenderFinalBal.Amount).To(Equal(txSenderInitialBal.Amount.Sub(fees)))
+
+					// check caller contract's final balance should be zero
+					callerContractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+					Expect(callerContractFinalBal.Amount).To(Equal(math.ZeroInt()))
+
+					// check destination contract's final balance should
+					// have received the clawback amt
+					destContractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, destContractAddr.Bytes(), s.bondDenom)
+					Expect(destContractFinalBal.Amount).To(Equal(destContractInitialBal.Amount.Add(expClawbackAmt)))
+				})
+
+				It(fmt.Sprintf("another contract as destination - should claw back from the vesting when sending as the funder with another smart contract as destination and triggering state change on destination contract (%s)", callType.name), func() {
+					if callType.directCall {
+						Skip("this should only be run for smart contract calls")
+					}
+					counterContract, err := contracts.LoadCounterContract()
+					Expect(err).ToNot(HaveOccurred())
+
+					destContractAddr, err := s.DeployContract(counterContract)
+					Expect(err).ToNot(HaveOccurred(), "error while deploying the smart contract: %v", err)
+
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					// check the contract's (destination) intial balance. Should be 0
+					destContractInitialBal := s.app.BankKeeper.GetBalance(s.ctx, destContractAddr.Bytes(), s.bondDenom)
+					Expect(destContractInitialBal.Amount).To(Equal(sdk.ZeroInt()))
+
+					// get tx sender initial balance
+					txSenderInitialBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName("clawbackWithCounterCall").
+						WithArgs(
+							s.address,
+							toAddr,
+							destContractAddr,
+						).
+						WithGasPrice(gasPrice.BigInt())
+
+					// expect the vesting precompile events and the Counter
+					// contract's events
+					clawbackCheck := passCheck.
+						WithABIEvents(mergeEventMaps(
+							s.precompile.Events,
+							counterContract.ABI.Events,
+						)).
+						WithExpEvents([]string{
+							"Added", "Changed",
+							vesting.EventTypeClawback,
+							"Changed",
+						}...)
+
+					res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
+					Expect(err).NotTo(HaveOccurred())
+					fees := gasPrice.MulRaw(res.GasUsed)
+
+					// check clawback account balance
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost.Amount).To(Equal(balancePre.Amount.Sub(expClawbackAmt)))
+
+					// check that tx signer's balance is reduced by the fees paid
+					txSenderFinalBal := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom)
+					Expect(txSenderFinalBal.Amount).To(Equal(txSenderInitialBal.Amount.Sub(fees)))
+
+					// check caller contract's final balance should be zero
+					callerContractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom)
+					Expect(callerContractFinalBal.Amount).To(Equal(math.ZeroInt()))
+
+					// check destination contract's final balance should
+					// have received the clawback amt
+					destContractFinalBal := s.app.BankKeeper.GetBalance(s.ctx, destContractAddr.Bytes(), s.bondDenom)
+					Expect(destContractFinalBal.Amount).To(Equal(destContractInitialBal.Amount.Add(expClawbackAmt)))
+				})
+
+				It(fmt.Sprintf("should return an error when not sending as the funder (%s)", callType.name), func() {
+					// create and fund new account
+					differentAddr, differentPriv := testutiltx.NewAddrKey()
+					err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, differentAddr.Bytes(), 1e18)
+					Expect(err).ToNot(HaveOccurred(), "error while funding the account: %v", err)
+
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName(vesting.ClawbackMethod).
+						WithPrivKey(differentPriv).
+						WithArgs(
+							s.address,
+							toAddr,
+							differentAddr,
+						)
 
-				balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
-				Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+					clawbackCheck := execRevertedCheck
+					if callType.directCall {
+						clawbackCheck = failCheck.
+							WithErrContains(fmt.Sprintf(
+								"tx origin address %s does not match the funder address %s",
+								differentAddr, s.address,
+							))
+					}
+
+					_, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
+					Expect(err).To(HaveOccurred(), "error while calling the contract: %v", err)
+					if callType.directCall {
+						Expect(err.Error()).To(ContainSubstring("does not match the funder address"))
+					}
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost).To(Equal(balancePre), "expected balance not to have changed")
+				})
+
+				It(fmt.Sprintf("should return an error when the vesting does not exist (%s)", callType.name), func() {
+					// fund the new account
+					err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, differentAddr.Bytes(), 1e18)
+					Expect(err).ToNot(HaveOccurred(), "error while funding the account: %v", err)
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName(vesting.ClawbackMethod).
+						WithArgs(
+							s.address,
+							differentAddr,
+							s.address,
+						)
 
-				clawbackArgs := s.BuildCallArgs(callType, contractAddr).
-					WithMethodName(vesting.ClawbackMethod).
-					WithArgs(
-						s.address,
-						toAddr,
-						s.address,
-					)
+					clawbackCheck := execRevertedCheck
+					if callType.directCall {
+						clawbackCheck = failCheck.
+							WithErrContains(vestingtypes.ErrNotSubjectToClawback.Error())
+					}
+
+					_, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, clawbackCheck)
+					Expect(err).To(HaveOccurred(), "error while calling the contract: %v", err)
+					if callType.directCall {
+						Expect(err.Error()).To(ContainSubstring("%s: %s", sdk.AccAddress(differentAddr.Bytes()), vestingtypes.ErrNotSubjectToClawback.Error()))
+					}
+				})
+
+				It(fmt.Sprintf("should succeed and return empty Coins when all tokens are vested (%s)", callType.name), func() {
+					// commit block with time so that vesting has ended
+					ctx, err := evmosutil.CommitAndCreateNewCtx(s.ctx, s.app, time.Hour*24, nil)
+					Expect(err).ToNot(HaveOccurred(), "error while committing block: %v", err)
+					s.ctx = ctx
+
+					balancePre := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePre.Amount).To(Equal(math.NewInt(1100)), "expected different balance after setup")
+
+					clawbackArgs := s.BuildCallArgs(callType, contractAddr).
+						WithMethodName(vesting.ClawbackMethod).
+						WithArgs(
+							s.address,
+							toAddr,
+							s.address,
+						)
 
-				_, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, passCheck)
-				Expect(err).To(HaveOccurred(), "error while calling the contract: %v", err)
+					_, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, clawbackArgs, passCheck)
+					Expect(err).To(HaveOccurred(), "error while calling the contract: %v", err)
 
-				var co vesting.ClawbackOutput
-				err = s.precompile.UnpackIntoInterface(&co, vesting.ClawbackMethod, ethRes.Ret)
-				Expect(err).ToNot(HaveOccurred(), "error while unpacking the clawback output: %v", err)
-				Expect(co.Coins).To(BeEmpty(), "expected empty clawback amount")
+					var co vesting.ClawbackOutput
+					err = s.precompile.UnpackIntoInterface(&co, vesting.ClawbackMethod, ethRes.Ret)
+					Expect(err).ToNot(HaveOccurred(), "error while unpacking the clawback output: %v", err)
+					Expect(co.Coins).To(BeEmpty(), "expected empty clawback amount")
 
-				balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
-				Expect(balancePost).To(Equal(balancePre), "expected balance not to have changed")
+					balancePost := s.app.BankKeeper.GetBalance(s.ctx, toAddr.Bytes(), s.bondDenom)
+					Expect(balancePost).To(Equal(balancePre), "expected balance not to have changed")
+				})
 			})
 		}
 	})

programming_language: Go
filename: VestingCaller.json
change_type: ModificationType.MODIFY
diff: @@ -109,6 +109,149 @@
       "stateMutability": "nonpayable",
       "type": "function"
     },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "funder",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "account",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "dest",
+          "type": "address"
+        }
+      ],
+      "name": "clawbackWithCounterCall",
+      "outputs": [
+        {
+          "components": [
+            {
+              "internalType": "string",
+              "name": "denom",
+              "type": "string"
+            },
+            {
+              "internalType": "uint256",
+              "name": "amount",
+              "type": "uint256"
+            }
+          ],
+          "internalType": "struct Coin[]",
+          "name": "coins",
+          "type": "tuple[]"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "funder",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "account",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "dest",
+          "type": "address"
+        },
+        {
+          "internalType": "bool",
+          "name": "before",
+          "type": "bool"
+        }
+      ],
+      "name": "clawbackWithRevert",
+      "outputs": [
+        {
+          "components": [
+            {
+              "internalType": "string",
+              "name": "denom",
+              "type": "string"
+            },
+            {
+              "internalType": "uint256",
+              "name": "amount",
+              "type": "uint256"
+            }
+          ],
+          "internalType": "struct Coin[]",
+          "name": "coins",
+          "type": "tuple[]"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "funder",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "account",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "dest",
+          "type": "address"
+        },
+        {
+          "internalType": "address payable",
+          "name": "_transferTo",
+          "type": "address"
+        },
+        {
+          "internalType": "bool",
+          "name": "_before",
+          "type": "bool"
+        },
+        {
+          "internalType": "bool",
+          "name": "_after",
+          "type": "bool"
+        }
+      ],
+      "name": "clawbackWithTransfer",
+      "outputs": [
+        {
+          "components": [
+            {
+              "internalType": "string",
+              "name": "denom",
+              "type": "string"
+            },
+            {
+              "internalType": "uint256",
+              "name": "amount",
+              "type": "uint256"
+            }
+          ],
+          "internalType": "struct Coin[]",
+          "name": "coins",
+          "type": "tuple[]"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
     {
       "inputs": [
         {
@@ -122,6 +265,19 @@
       "stateMutability": "nonpayable",
       "type": "function"
     },
+    {
+      "inputs": [],
+      "name": "counter",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
     {
       "inputs": [
         {
@@ -233,6 +389,183 @@
       "stateMutability": "nonpayable",
       "type": "function"
     },
+    {
+      "inputs": [
+        {
+          "internalType": "address payable",
+          "name": "funder",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "to",
+          "type": "address"
+        },
+        {
+          "internalType": "address payable",
+          "name": "_transferTo",
+          "type": "address"
+        },
+        {
+          "internalType": "uint64",
+          "name": "startTime",
+          "type": "uint64"
+        },
+        {
+          "components": [
+            {
+              "internalType": "int64",
+              "name": "length",
+              "type": "int64"
+            },
+            {
+              "components": [
+                {
+                  "internalType": "string",
+                  "name": "denom",
+                  "type": "string"
+                },
+                {
+                  "internalType": "uint256",
+                  "name": "amount",
+                  "type": "uint256"
+                }
+              ],
+              "internalType": "struct Coin[]",
+              "name": "amount",
+              "type": "tuple[]"
+            }
+          ],
+          "internalType": "struct Period[]",
+          "name": "lockupPeriods",
+          "type": "tuple[]"
+        },
+        {
+          "components": [
+            {
+              "internalType": "int64",
+              "name": "length",
+              "type": "int64"
+            },
+            {
+              "components": [
+                {
+                  "internalType": "string",
+                  "name": "denom",
+                  "type": "string"
+                },
+                {
+                  "internalType": "uint256",
+                  "name": "amount",
+                  "type": "uint256"
+                }
+              ],
+              "internalType": "struct Coin[]",
+              "name": "amount",
+              "type": "tuple[]"
+            }
+          ],
+          "internalType": "struct Period[]",
+          "name": "vestingPeriods",
+          "type": "tuple[]"
+        },
+        {
+          "internalType": "bool",
+          "name": "transferBefore",
+          "type": "bool"
+        },
+        {
+          "internalType": "bool",
+          "name": "transferAfter",
+          "type": "bool"
+        }
+      ],
+      "name": "fundVestingAccountAndTransfer",
+      "outputs": [],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "funder",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "to",
+          "type": "address"
+        },
+        {
+          "internalType": "uint64",
+          "name": "startTime",
+          "type": "uint64"
+        },
+        {
+          "components": [
+            {
+              "internalType": "int64",
+              "name": "length",
+              "type": "int64"
+            },
+            {
+              "components": [
+                {
+                  "internalType": "string",
+                  "name": "denom",
+                  "type": "string"
+                },
+                {
+                  "internalType": "uint256",
+                  "name": "amount",
+                  "type": "uint256"
+                }
+              ],
+              "internalType": "struct Coin[]",
+              "name": "amount",
+              "type": "tuple[]"
+            }
+          ],
+          "internalType": "struct Period[]",
+          "name": "lockupPeriods",
+          "type": "tuple[]"
+        },
+        {
+          "components": [
+            {
+              "internalType": "int64",
+              "name": "length",
+              "type": "int64"
+            },
+            {
+              "components": [
+                {
+                  "internalType": "string",
+                  "name": "denom",
+                  "type": "string"
+                },
+                {
+                  "internalType": "uint256",
+                  "name": "amount",
+                  "type": "uint256"
+                }
+              ],
+              "internalType": "struct Coin[]",
+              "name": "amount",
+              "type": "tuple[]"
+            }
+          ],
+          "internalType": "struct Period[]",
+          "name": "vestingPeriods",
+          "type": "tuple[]"
+        }
+      ],
+      "name": "fundVestingAccountWithCounterContract",
+      "outputs": [],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
     {
       "inputs": [
         {
@@ -257,8 +590,8 @@
       "type": "function"
     }
   ],
-  "bytecode": "0x608060405234801561001057600080fd5b50611707806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806372e7c9ab1161005b57806372e7c9ab146100ec5780637caef81b1461011c5780639cfef12914610126578063cdb50175146101425761007d565b806327e235e3146100825780634fe1a8df146100b45780635a211064146100d0575b600080fd5b61009c600480360381019061009791906106f5565b61015e565b6040516100ab939291906108ca565b60405180910390f35b6100ce60048036038101906100c991906109bb565b6101f1565b005b6100ea60048036038101906100e591906106f5565b6102c9565b005b61010660048036038101906101019190610a77565b61038f565b6040516101139190610aca565b60405180910390f35b610124610421565b005b610140600480360381019061013b9190610a77565b6104eb565b005b61015c60048036038101906101579190610b24565b6105b7565b005b606080606061080373ffffffffffffffffffffffffffffffffffffffff166327e235e3856040518263ffffffff1660e01b815260040161019e9190610b86565b600060405180830381865afa1580156101bb573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906101e49190610e45565b9250925092509193909250565b600061080373ffffffffffffffffffffffffffffffffffffffff16634fe1a8df898989898989896040518863ffffffff1660e01b815260040161023a97969594939291906112e5565b6020604051808303816000875af1158015610259573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061027d919061135f565b9050806102bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102b69061140f565b60405180910390fd5b5050505050505050565b600061080373ffffffffffffffffffffffffffffffffffffffff16635a211064836040518263ffffffff1660e01b81526004016103069190610b86565b6020604051808303816000875af1158015610325573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610349919061135f565b90508061038b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610382906114a1565b60405180910390fd5b5050565b606061080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8585856040518463ffffffff1660e01b81526004016103d0939291906114c1565b6000604051808303816000875af11580156103ef573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061041891906114f8565b90509392505050565b600061080373ffffffffffffffffffffffffffffffffffffffff1663cdb50175333060006040518463ffffffff1660e01b815260040161046393929190611550565b6020604051808303816000875af1158015610482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a6919061135f565b9050806104e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104df9061161f565b60405180910390fd5b50565b600061080373ffffffffffffffffffffffffffffffffffffffff16639cfef1298585856040518463ffffffff1660e01b815260040161052c939291906114c1565b6020604051808303816000875af115801561054b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056f919061135f565b9050806105b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a8906116b1565b60405180910390fd5b50505050565b600061080373ffffffffffffffffffffffffffffffffffffffff1663cdb501758585856040518463ffffffff1660e01b81526004016105f893929190611550565b6020604051808303816000875af1158015610617573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063b919061135f565b90508061067d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106749061140f565b60405180910390fd5b50505050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106c282610697565b9050919050565b6106d2816106b7565b81146106dd57600080fd5b50565b6000813590506106ef816106c9565b92915050565b60006020828403121561070b5761070a61068d565b5b6000610719848285016106e0565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561078857808201518184015260208101905061076d565b60008484015250505050565b6000601f19601f8301169050919050565b60006107b08261074e565b6107ba8185610759565b93506107ca81856020860161076a565b6107d381610794565b840191505092915050565b6000819050919050565b6107f1816107de565b82525050565b6000604083016000830151848203600086015261081482826107a5565b915050602083015161082960208601826107e8565b508091505092915050565b600061084083836107f7565b905092915050565b6000602082019050919050565b600061086082610722565b61086a818561072d565b93508360208202850161087c8561073e565b8060005b858110156108b857848403895281516108998582610834565b94506108a483610848565b925060208a01995050600181019050610880565b50829750879550505050505092915050565b600060608201905081810360008301526108e48186610855565b905081810360208301526108f88185610855565b9050818103604083015261090c8184610855565b9050949350505050565b600067ffffffffffffffff82169050919050565b61093381610916565b811461093e57600080fd5b50565b6000813590506109508161092a565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261097b5761097a610956565b5b8235905067ffffffffffffffff8111156109985761099761095b565b5b6020830191508360208202830111156109b4576109b3610960565b5b9250929050565b600080600080600080600060a0888a0312156109da576109d961068d565b5b60006109e88a828b016106e0565b97505060206109f98a828b016106e0565b9650506040610a0a8a828b01610941565b955050606088013567ffffffffffffffff811115610a2b57610a2a610692565b5b610a378a828b01610965565b9450945050608088013567ffffffffffffffff811115610a5a57610a59610692565b5b610a668a828b01610965565b925092505092959891949750929550565b600080600060608486031215610a9057610a8f61068d565b5b6000610a9e868287016106e0565b9350506020610aaf868287016106e0565b9250506040610ac0868287016106e0565b9150509250925092565b60006020820190508181036000830152610ae48184610855565b905092915050565b60008115159050919050565b610b0181610aec565b8114610b0c57600080fd5b50565b600081359050610b1e81610af8565b92915050565b600080600060608486031215610b3d57610b3c61068d565b5b6000610b4b868287016106e0565b9350506020610b5c868287016106e0565b9250506040610b6d86828701610b0f565b9150509250925092565b610b80816106b7565b82525050565b6000602082019050610b9b6000830184610b77565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610bd982610794565b810181811067ffffffffffffffff82111715610bf857610bf7610ba1565b5b80604052505050565b6000610c0b610683565b9050610c178282610bd0565b919050565b600067ffffffffffffffff821115610c3757610c36610ba1565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff821115610c7257610c71610ba1565b5b610c7b82610794565b9050602081019050919050565b6000610c9b610c9684610c57565b610c01565b905082815260208101848484011115610cb757610cb6610c52565b5b610cc284828561076a565b509392505050565b600082601f830112610cdf57610cde610956565b5b8151610cef848260208601610c88565b91505092915050565b610d01816107de565b8114610d0c57600080fd5b50565b600081519050610d1e81610cf8565b92915050565b600060408284031215610d3a57610d39610c48565b5b610d446040610c01565b9050600082015167ffffffffffffffff811115610d6457610d63610c4d565b5b610d7084828501610cca565b6000830152506020610d8484828501610d0f565b60208301525092915050565b6000610da3610d9e84610c1c565b610c01565b90508083825260208201905060208402830185811115610dc657610dc5610960565b5b835b81811015610e0d57805167ffffffffffffffff811115610deb57610dea610956565b5b808601610df88982610d24565b85526020850194505050602081019050610dc8565b5050509392505050565b600082601f830112610e2c57610e2b610956565b5b8151610e3c848260208601610d90565b91505092915050565b600080600060608486031215610e5e57610e5d61068d565b5b600084015167ffffffffffffffff811115610e7c57610e7b610692565b5b610e8886828701610e17565b935050602084015167ffffffffffffffff811115610ea957610ea8610692565b5b610eb586828701610e17565b925050604084015167ffffffffffffffff811115610ed657610ed5610692565b5b610ee286828701610e17565b9150509250925092565b610ef581610916565b82525050565b600082825260208201905092915050565b6000819050919050565b60008160070b9050919050565b610f2c81610f16565b8114610f3757600080fd5b50565b600081359050610f4981610f23565b92915050565b6000610f5e6020840184610f3a565b905092915050565b610f6f81610f16565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610fa157610fa0610f7f565b5b83810192508235915060208301925067ffffffffffffffff821115610fc957610fc8610f75565b5b602082023603831315610fdf57610fde610f7a565b5b509250929050565b600082825260208201905092915050565b6000819050919050565b6000808335600160200384360303811261101f5761101e610f7f565b5b83810192508235915060208301925067ffffffffffffffff82111561104757611046610f75565b5b60018202360383131561105d5761105c610f7a565b5b509250929050565b82818337600083830152505050565b60006110808385610759565b935061108d838584611065565b61109683610794565b840190509392505050565b6000813590506110b081610cf8565b92915050565b60006110c560208401846110a1565b905092915050565b6000604083016110e06000840184611002565b85830360008701526110f3838284611074565b9250505061110460208401846110b6565b61111160208601826107e8565b508091505092915050565b600061112883836110cd565b905092915050565b60008235600160400383360303811261114c5761114b610f7f565b5b82810191505092915050565b6000602082019050919050565b60006111718385610fe7565b93508360208402850161118384610ff8565b8060005b878110156111c757848403895261119e8284611130565b6111a8858261111c565b94506111b383611158565b925060208a01995050600181019050611187565b50829750879450505050509392505050565b6000604083016111ec6000840184610f4f565b6111f96000860182610f66565b506112076020840184610f84565b858303602087015261121a838284611165565b925050508091505092915050565b600061123483836111d9565b905092915050565b60008235600160400383360303811261125857611257610f7f565b5b82810191505092915050565b6000602082019050919050565b600061127d8385610efb565b93508360208402850161128f84610f0c565b8060005b878110156112d35784840389526112aa828461123c565b6112b48582611228565b94506112bf83611264565b925060208a01995050600181019050611293565b50829750879450505050509392505050565b600060a0820190506112fa600083018a610b77565b6113076020830189610b77565b6113146040830188610eec565b8181036060830152611327818688611271565b9050818103608083015261133c818486611271565b905098975050505050505050565b60008151905061135981610af8565b92915050565b6000602082840312156113755761137461068d565b5b60006113838482850161134a565b91505092915050565b600082825260208201905092915050565b7f56657374696e6743616c6c65723a2063726561746520636c61776261636b207660008201527f657374696e67206163636f756e74206661696c65640000000000000000000000602082015250565b60006113f960358361138c565b91506114048261139d565b604082019050919050565b60006020820190508181036000830152611428816113ec565b9050919050565b7f56657374696e6743616c6c65723a20636f6e7665727420746f20636c6177626160008201527f636b2076657374696e67206163636f756e74206661696c656400000000000000602082015250565b600061148b60398361138c565b91506114968261142f565b604082019050919050565b600060208201905081810360008301526114ba8161147e565b9050919050565b60006060820190506114d66000830186610b77565b6114e36020830185610b77565b6114f06040830184610b77565b949350505050565b60006020828403121561150e5761150d61068d565b5b600082015167ffffffffffffffff81111561152c5761152b610692565b5b61153884828501610e17565b91505092915050565b61154a81610aec565b82525050565b60006060820190506115656000830186610b77565b6115726020830185610b77565b61157f6040830184611541565b949350505050565b7f56657374696e6743616c6c65723a2063726561746520636c61776261636b207660008201527f657374696e67206163636f756e7420666f7220636f6e7472616374206661696c60208201527f6564000000000000000000000000000000000000000000000000000000000000604082015250565b600061160960428361138c565b915061161482611587565b606082019050919050565b60006020820190508181036000830152611638816115fc565b9050919050565b7f56657374696e6743616c6c65723a207570646174652076657374696e6720667560008201527f6e646572206661696c6564000000000000000000000000000000000000000000602082015250565b600061169b602b8361138c565b91506116a68261163f565b604082019050919050565b600060208201905081810360008301526116ca8161168e565b905091905056fea2646970667358221220b5591174fd0eae8c3194a72e4046b55353e35d6f0b4613d06bca7876629b922764736f6c63430008130033",
-  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c806372e7c9ab1161005b57806372e7c9ab146100ec5780637caef81b1461011c5780639cfef12914610126578063cdb50175146101425761007d565b806327e235e3146100825780634fe1a8df146100b45780635a211064146100d0575b600080fd5b61009c600480360381019061009791906106f5565b61015e565b6040516100ab939291906108ca565b60405180910390f35b6100ce60048036038101906100c991906109bb565b6101f1565b005b6100ea60048036038101906100e591906106f5565b6102c9565b005b61010660048036038101906101019190610a77565b61038f565b6040516101139190610aca565b60405180910390f35b610124610421565b005b610140600480360381019061013b9190610a77565b6104eb565b005b61015c60048036038101906101579190610b24565b6105b7565b005b606080606061080373ffffffffffffffffffffffffffffffffffffffff166327e235e3856040518263ffffffff1660e01b815260040161019e9190610b86565b600060405180830381865afa1580156101bb573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906101e49190610e45565b9250925092509193909250565b600061080373ffffffffffffffffffffffffffffffffffffffff16634fe1a8df898989898989896040518863ffffffff1660e01b815260040161023a97969594939291906112e5565b6020604051808303816000875af1158015610259573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061027d919061135f565b9050806102bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102b69061140f565b60405180910390fd5b5050505050505050565b600061080373ffffffffffffffffffffffffffffffffffffffff16635a211064836040518263ffffffff1660e01b81526004016103069190610b86565b6020604051808303816000875af1158015610325573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610349919061135f565b90508061038b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610382906114a1565b60405180910390fd5b5050565b606061080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8585856040518463ffffffff1660e01b81526004016103d0939291906114c1565b6000604051808303816000875af11580156103ef573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061041891906114f8565b90509392505050565b600061080373ffffffffffffffffffffffffffffffffffffffff1663cdb50175333060006040518463ffffffff1660e01b815260040161046393929190611550565b6020604051808303816000875af1158015610482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a6919061135f565b9050806104e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104df9061161f565b60405180910390fd5b50565b600061080373ffffffffffffffffffffffffffffffffffffffff16639cfef1298585856040518463ffffffff1660e01b815260040161052c939291906114c1565b6020604051808303816000875af115801561054b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056f919061135f565b9050806105b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a8906116b1565b60405180910390fd5b50505050565b600061080373ffffffffffffffffffffffffffffffffffffffff1663cdb501758585856040518463ffffffff1660e01b81526004016105f893929190611550565b6020604051808303816000875af1158015610617573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063b919061135f565b90508061067d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106749061140f565b60405180910390fd5b50505050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106c282610697565b9050919050565b6106d2816106b7565b81146106dd57600080fd5b50565b6000813590506106ef816106c9565b92915050565b60006020828403121561070b5761070a61068d565b5b6000610719848285016106e0565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561078857808201518184015260208101905061076d565b60008484015250505050565b6000601f19601f8301169050919050565b60006107b08261074e565b6107ba8185610759565b93506107ca81856020860161076a565b6107d381610794565b840191505092915050565b6000819050919050565b6107f1816107de565b82525050565b6000604083016000830151848203600086015261081482826107a5565b915050602083015161082960208601826107e8565b508091505092915050565b600061084083836107f7565b905092915050565b6000602082019050919050565b600061086082610722565b61086a818561072d565b93508360208202850161087c8561073e565b8060005b858110156108b857848403895281516108998582610834565b94506108a483610848565b925060208a01995050600181019050610880565b50829750879550505050505092915050565b600060608201905081810360008301526108e48186610855565b905081810360208301526108f88185610855565b9050818103604083015261090c8184610855565b9050949350505050565b600067ffffffffffffffff82169050919050565b61093381610916565b811461093e57600080fd5b50565b6000813590506109508161092a565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261097b5761097a610956565b5b8235905067ffffffffffffffff8111156109985761099761095b565b5b6020830191508360208202830111156109b4576109b3610960565b5b9250929050565b600080600080600080600060a0888a0312156109da576109d961068d565b5b60006109e88a828b016106e0565b97505060206109f98a828b016106e0565b9650506040610a0a8a828b01610941565b955050606088013567ffffffffffffffff811115610a2b57610a2a610692565b5b610a378a828b01610965565b9450945050608088013567ffffffffffffffff811115610a5a57610a59610692565b5b610a668a828b01610965565b925092505092959891949750929550565b600080600060608486031215610a9057610a8f61068d565b5b6000610a9e868287016106e0565b9350506020610aaf868287016106e0565b9250506040610ac0868287016106e0565b9150509250925092565b60006020820190508181036000830152610ae48184610855565b905092915050565b60008115159050919050565b610b0181610aec565b8114610b0c57600080fd5b50565b600081359050610b1e81610af8565b92915050565b600080600060608486031215610b3d57610b3c61068d565b5b6000610b4b868287016106e0565b9350506020610b5c868287016106e0565b9250506040610b6d86828701610b0f565b9150509250925092565b610b80816106b7565b82525050565b6000602082019050610b9b6000830184610b77565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610bd982610794565b810181811067ffffffffffffffff82111715610bf857610bf7610ba1565b5b80604052505050565b6000610c0b610683565b9050610c178282610bd0565b919050565b600067ffffffffffffffff821115610c3757610c36610ba1565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff821115610c7257610c71610ba1565b5b610c7b82610794565b9050602081019050919050565b6000610c9b610c9684610c57565b610c01565b905082815260208101848484011115610cb757610cb6610c52565b5b610cc284828561076a565b509392505050565b600082601f830112610cdf57610cde610956565b5b8151610cef848260208601610c88565b91505092915050565b610d01816107de565b8114610d0c57600080fd5b50565b600081519050610d1e81610cf8565b92915050565b600060408284031215610d3a57610d39610c48565b5b610d446040610c01565b9050600082015167ffffffffffffffff811115610d6457610d63610c4d565b5b610d7084828501610cca565b6000830152506020610d8484828501610d0f565b60208301525092915050565b6000610da3610d9e84610c1c565b610c01565b90508083825260208201905060208402830185811115610dc657610dc5610960565b5b835b81811015610e0d57805167ffffffffffffffff811115610deb57610dea610956565b5b808601610df88982610d24565b85526020850194505050602081019050610dc8565b5050509392505050565b600082601f830112610e2c57610e2b610956565b5b8151610e3c848260208601610d90565b91505092915050565b600080600060608486031215610e5e57610e5d61068d565b5b600084015167ffffffffffffffff811115610e7c57610e7b610692565b5b610e8886828701610e17565b935050602084015167ffffffffffffffff811115610ea957610ea8610692565b5b610eb586828701610e17565b925050604084015167ffffffffffffffff811115610ed657610ed5610692565b5b610ee286828701610e17565b9150509250925092565b610ef581610916565b82525050565b600082825260208201905092915050565b6000819050919050565b60008160070b9050919050565b610f2c81610f16565b8114610f3757600080fd5b50565b600081359050610f4981610f23565b92915050565b6000610f5e6020840184610f3a565b905092915050565b610f6f81610f16565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610fa157610fa0610f7f565b5b83810192508235915060208301925067ffffffffffffffff821115610fc957610fc8610f75565b5b602082023603831315610fdf57610fde610f7a565b5b509250929050565b600082825260208201905092915050565b6000819050919050565b6000808335600160200384360303811261101f5761101e610f7f565b5b83810192508235915060208301925067ffffffffffffffff82111561104757611046610f75565b5b60018202360383131561105d5761105c610f7a565b5b509250929050565b82818337600083830152505050565b60006110808385610759565b935061108d838584611065565b61109683610794565b840190509392505050565b6000813590506110b081610cf8565b92915050565b60006110c560208401846110a1565b905092915050565b6000604083016110e06000840184611002565b85830360008701526110f3838284611074565b9250505061110460208401846110b6565b61111160208601826107e8565b508091505092915050565b600061112883836110cd565b905092915050565b60008235600160400383360303811261114c5761114b610f7f565b5b82810191505092915050565b6000602082019050919050565b60006111718385610fe7565b93508360208402850161118384610ff8565b8060005b878110156111c757848403895261119e8284611130565b6111a8858261111c565b94506111b383611158565b925060208a01995050600181019050611187565b50829750879450505050509392505050565b6000604083016111ec6000840184610f4f565b6111f96000860182610f66565b506112076020840184610f84565b858303602087015261121a838284611165565b925050508091505092915050565b600061123483836111d9565b905092915050565b60008235600160400383360303811261125857611257610f7f565b5b82810191505092915050565b6000602082019050919050565b600061127d8385610efb565b93508360208402850161128f84610f0c565b8060005b878110156112d35784840389526112aa828461123c565b6112b48582611228565b94506112bf83611264565b925060208a01995050600181019050611293565b50829750879450505050509392505050565b600060a0820190506112fa600083018a610b77565b6113076020830189610b77565b6113146040830188610eec565b8181036060830152611327818688611271565b9050818103608083015261133c818486611271565b905098975050505050505050565b60008151905061135981610af8565b92915050565b6000602082840312156113755761137461068d565b5b60006113838482850161134a565b91505092915050565b600082825260208201905092915050565b7f56657374696e6743616c6c65723a2063726561746520636c61776261636b207660008201527f657374696e67206163636f756e74206661696c65640000000000000000000000602082015250565b60006113f960358361138c565b91506114048261139d565b604082019050919050565b60006020820190508181036000830152611428816113ec565b9050919050565b7f56657374696e6743616c6c65723a20636f6e7665727420746f20636c6177626160008201527f636b2076657374696e67206163636f756e74206661696c656400000000000000602082015250565b600061148b60398361138c565b91506114968261142f565b604082019050919050565b600060208201905081810360008301526114ba8161147e565b9050919050565b60006060820190506114d66000830186610b77565b6114e36020830185610b77565b6114f06040830184610b77565b949350505050565b60006020828403121561150e5761150d61068d565b5b600082015167ffffffffffffffff81111561152c5761152b610692565b5b61153884828501610e17565b91505092915050565b61154a81610aec565b82525050565b60006060820190506115656000830186610b77565b6115726020830185610b77565b61157f6040830184611541565b949350505050565b7f56657374696e6743616c6c65723a2063726561746520636c61776261636b207660008201527f657374696e67206163636f756e7420666f7220636f6e7472616374206661696c60208201527f6564000000000000000000000000000000000000000000000000000000000000604082015250565b600061160960428361138c565b915061161482611587565b606082019050919050565b60006020820190508181036000830152611638816115fc565b9050919050565b7f56657374696e6743616c6c65723a207570646174652076657374696e6720667560008201527f6e646572206661696c6564000000000000000000000000000000000000000000602082015250565b600061169b602b8361138c565b91506116a68261163f565b604082019050919050565b600060208201905081810360008301526116ca8161168e565b905091905056fea2646970667358221220b5591174fd0eae8c3194a72e4046b55353e35d6f0b4613d06bca7876629b922764736f6c63430008130033",
+  "bytecode": "0x608060405234801561001057600080fd5b506127ac806100206000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80636c49d3031161008c5780638e292e40116100665780638e292e40146101fe5780639cfef1291461022e578063cdb501751461024a578063fc9c1a8714610266576100cf565b80636c49d303146101a857806372e7c9ab146101c45780637caef81b146101f4576100cf565b806303f4be50146100d45780631e9178bb1461010457806327e235e3146101205780634fe1a8df146101525780635a2110641461016e57806361bc221a1461018a575b600080fd5b6100ee60048036038101906100e99190611233565b610296565b6040516100fb919061142e565b60405180910390f35b61011e6004803603810190610119919061156b565b61041c565b005b61013a60048036038101906101359190611662565b61068f565b6040516101499392919061168f565b60405180910390f35b61016c600480360381019061016791906116db565b610722565b005b61018860048036038101906101839190611662565b610828565b005b6101926108ee565b60405161019f91906117a6565b60405180910390f35b6101c260048036038101906101bd91906116db565b6108f4565b005b6101de60048036038101906101d99190611233565b610ac0565b6040516101eb919061142e565b60405180910390f35b6101fc610b80565b005b610218600480360381019061021391906117c1565b610c4a565b604051610225919061142e565b60405180910390f35b61024860048036038101906102439190611233565b610d94565b005b610264600480360381019061025f9190611828565b610e60565b005b610280600480360381019061027b919061187b565b610f2c565b60405161028d919061142e565b60405180910390f35b606060008290508073ffffffffffffffffffffffffffffffffffffffff16634f2be91f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102e557600080fd5b505af11580156102f9573d6000803e3d6000fd5b5050505060008081548092919061030f90611937565b919050555061080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8686866040518463ffffffff1660e01b81526004016103539392919061198e565b6000604051808303816000875af1158015610372573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061039b9190611c69565b91508073ffffffffffffffffffffffffffffffffffffffff16636deebae36040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156103e557600080fd5b505af11580156103f9573d6000803e3d6000fd5b5050505060008081548092919061040f90611cb2565b9190505550509392505050565b81156104e85760008081548092919061043490611937565b919050555060008873ffffffffffffffffffffffffffffffffffffffff16600f60405161046090611d0c565b60006040518083038185875af1925050503d806000811461049d576040519150601f19603f3d011682016040523d82523d6000602084013e6104a2565b606091505b50509050806104e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104dd90611d7e565b60405180910390fd5b505b600061080373ffffffffffffffffffffffffffffffffffffffff16634fe1a8df8c8c8b8b8b8b8b6040518863ffffffff1660e01b815260040161053197969594939291906121f6565b6020604051808303816000875af1158015610550573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105749190612270565b9050806105b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ad9061230f565b60405180910390fd5b81156106825760008973ffffffffffffffffffffffffffffffffffffffff16600f6040516105e390611d0c565b60006040518083038185875af1925050503d8060008114610620576040519150601f19603f3d011682016040523d82523d6000602084013e610625565b606091505b5050905080610669576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066090611d7e565b60405180910390fd5b60008081548092919061067b90611937565b9190505550505b5050505050505050505050565b606080606061080373ffffffffffffffffffffffffffffffffffffffff166327e235e3856040518263ffffffff1660e01b81526004016106cf919061232f565b600060405180830381865afa1580156106ec573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610715919061234a565b9250925092509193909250565b60008081548092919061073490611937565b9190505550600061080373ffffffffffffffffffffffffffffffffffffffff16634fe1a8df898989898989896040518863ffffffff1660e01b815260040161078297969594939291906123f1565b6020604051808303816000875af11580156107a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c59190612270565b905080610807576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fe9061230f565b60405180910390fd5b60008081548092919061081990611cb2565b91905055505050505050505050565b600061080373ffffffffffffffffffffffffffffffffffffffff16635a211064836040518263ffffffff1660e01b8152600401610865919061232f565b6020604051808303816000875af1158015610884573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a89190612270565b9050806108ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906124c8565b60405180910390fd5b5050565b60005481565b60008790508073ffffffffffffffffffffffffffffffffffffffff16634f2be91f6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b5050505060008081548092919061096b90611937565b9190505550600061080373ffffffffffffffffffffffffffffffffffffffff16634fe1a8df8a8a8a8a8a8a8a6040518863ffffffff1660e01b81526004016109b997969594939291906123f1565b6020604051808303816000875af11580156109d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fc9190612270565b905080610a3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a359061230f565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16636deebae36040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a8657600080fd5b505af1158015610a9a573d6000803e3d6000fd5b50505050600080815480929190610ab090611cb2565b9190505550505050505050505050565b6060600080815480929190610ad490611937565b919050555061080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8585856040518463ffffffff1660e01b8152600401610b189392919061198e565b6000604051808303816000875af1158015610b37573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610b609190611c69565b9050600080815480929190610b7490611cb2565b91905055509392505050565b600061080373ffffffffffffffffffffffffffffffffffffffff1663cdb50175333060006040518463ffffffff1660e01b8152600401610bc2939291906124f7565b6020604051808303816000875af1158015610be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c059190612270565b905080610c47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3e906125c6565b60405180910390fd5b50565b6060600080815480929190610c5e90611937565b919050555061080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8686866040518463ffffffff1660e01b8152600401610ca29392919061198e565b6000604051808303816000875af1158015610cc1573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610cea9190611c69565b90508115610d34576000610d33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2a90612632565b60405180910390fd5b5b600080815480929190610d4690611cb2565b91905055506000610d8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8390612632565b60405180910390fd5b949350505050565b600061080373ffffffffffffffffffffffffffffffffffffffff16639cfef1298585856040518463ffffffff1660e01b8152600401610dd59392919061198e565b6020604051808303816000875af1158015610df4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e189190612270565b905080610e5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e51906126c4565b60405180910390fd5b50505050565b600061080373ffffffffffffffffffffffffffffffffffffffff1663cdb501758585856040518463ffffffff1660e01b8152600401610ea1939291906124f7565b6020604051808303816000875af1158015610ec0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee49190612270565b905080610f26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1d9061230f565b60405180910390fd5b50505050565b6060821561102e57600080815480929190610f4690611937565b91905055503073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161461102d5760008473ffffffffffffffffffffffffffffffffffffffff16600f604051610fa590611d0c565b60006040518083038185875af1925050503d8060008114610fe2576040519150601f19603f3d011682016040523d82523d6000602084013e610fe7565b606091505b505090508061102b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102290612756565b60405180910390fd5b505b5b61080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8888886040518463ffffffff1660e01b815260040161106d9392919061198e565b6000604051808303816000875af115801561108c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906110b59190611c69565b905081156111b7576000808154809291906110cf90611937565b91905055503073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146111b65760008473ffffffffffffffffffffffffffffffffffffffff16600f60405161112e90611d0c565b60006040518083038185875af1925050503d806000811461116b576040519150601f19603f3d011682016040523d82523d6000602084013e611170565b606091505b50509050806111b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ab90612756565b60405180910390fd5b505b5b9695505050505050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611200826111d5565b9050919050565b611210816111f5565b811461121b57600080fd5b50565b60008135905061122d81611207565b92915050565b60008060006060848603121561124c5761124b6111cb565b5b600061125a8682870161121e565b935050602061126b8682870161121e565b925050604061127c8682870161121e565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b838110156112ec5780820151818401526020810190506112d1565b60008484015250505050565b6000601f19601f8301169050919050565b6000611314826112b2565b61131e81856112bd565b935061132e8185602086016112ce565b611337816112f8565b840191505092915050565b6000819050919050565b61135581611342565b82525050565b600060408301600083015184820360008601526113788282611309565b915050602083015161138d602086018261134c565b508091505092915050565b60006113a4838361135b565b905092915050565b6000602082019050919050565b60006113c482611286565b6113ce8185611291565b9350836020820285016113e0856112a2565b8060005b8581101561141c57848403895281516113fd8582611398565b9450611408836113ac565b925060208a019950506001810190506113e4565b50829750879550505050505092915050565b6000602082019050818103600083015261144881846113b9565b905092915050565b600061145b826111d5565b9050919050565b61146b81611450565b811461147657600080fd5b50565b60008135905061148881611462565b92915050565b600067ffffffffffffffff82169050919050565b6114ab8161148e565b81146114b657600080fd5b50565b6000813590506114c8816114a2565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126114f3576114f26114ce565b5b8235905067ffffffffffffffff8111156115105761150f6114d3565b5b60208301915083602082028301111561152c5761152b6114d8565b5b9250929050565b60008115159050919050565b61154881611533565b811461155357600080fd5b50565b6000813590506115658161153f565b92915050565b6000806000806000806000806000806101008b8d03121561158f5761158e6111cb565b5b600061159d8d828e01611479565b9a505060206115ae8d828e0161121e565b99505060406115bf8d828e01611479565b98505060606115d08d828e016114b9565b97505060808b013567ffffffffffffffff8111156115f1576115f06111d0565b5b6115fd8d828e016114dd565b965096505060a08b013567ffffffffffffffff8111156116205761161f6111d0565b5b61162c8d828e016114dd565b945094505060c061163f8d828e01611556565b92505060e06116508d828e01611556565b9150509295989b9194979a5092959850565b600060208284031215611678576116776111cb565b5b60006116868482850161121e565b91505092915050565b600060608201905081810360008301526116a981866113b9565b905081810360208301526116bd81856113b9565b905081810360408301526116d181846113b9565b9050949350505050565b600080600080600080600060a0888a0312156116fa576116f96111cb565b5b60006117088a828b0161121e565b97505060206117198a828b0161121e565b965050604061172a8a828b016114b9565b955050606088013567ffffffffffffffff81111561174b5761174a6111d0565b5b6117578a828b016114dd565b9450945050608088013567ffffffffffffffff81111561177a576117796111d0565b5b6117868a828b016114dd565b925092505092959891949750929550565b6117a081611342565b82525050565b60006020820190506117bb6000830184611797565b92915050565b600080600080608085870312156117db576117da6111cb565b5b60006117e98782880161121e565b94505060206117fa8782880161121e565b935050604061180b8782880161121e565b925050606061181c87828801611556565b91505092959194509250565b600080600060608486031215611841576118406111cb565b5b600061184f8682870161121e565b93505060206118608682870161121e565b925050604061187186828701611556565b9150509250925092565b60008060008060008060c08789031215611898576118976111cb565b5b60006118a689828a0161121e565b96505060206118b789828a0161121e565b95505060406118c889828a0161121e565b94505060606118d989828a01611479565b93505060806118ea89828a01611556565b92505060a06118fb89828a01611556565b9150509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061194282611342565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361197457611973611908565b5b600182019050919050565b611988816111f5565b82525050565b60006060820190506119a3600083018661197f565b6119b0602083018561197f565b6119bd604083018461197f565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6119fd826112f8565b810181811067ffffffffffffffff82111715611a1c57611a1b6119c5565b5b80604052505050565b6000611a2f6111c1565b9050611a3b82826119f4565b919050565b600067ffffffffffffffff821115611a5b57611a5a6119c5565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff821115611a9657611a956119c5565b5b611a9f826112f8565b9050602081019050919050565b6000611abf611aba84611a7b565b611a25565b905082815260208101848484011115611adb57611ada611a76565b5b611ae68482856112ce565b509392505050565b600082601f830112611b0357611b026114ce565b5b8151611b13848260208601611aac565b91505092915050565b611b2581611342565b8114611b3057600080fd5b50565b600081519050611b4281611b1c565b92915050565b600060408284031215611b5e57611b5d611a6c565b5b611b686040611a25565b9050600082015167ffffffffffffffff811115611b8857611b87611a71565b5b611b9484828501611aee565b6000830152506020611ba884828501611b33565b60208301525092915050565b6000611bc7611bc284611a40565b611a25565b90508083825260208201905060208402830185811115611bea57611be96114d8565b5b835b81811015611c3157805167ffffffffffffffff811115611c0f57611c0e6114ce565b5b808601611c1c8982611b48565b85526020850194505050602081019050611bec565b5050509392505050565b600082601f830112611c5057611c4f6114ce565b5b8151611c60848260208601611bb4565b91505092915050565b600060208284031215611c7f57611c7e6111cb565b5b600082015167ffffffffffffffff811115611c9d57611c9c6111d0565b5b611ca984828501611c3b565b91505092915050565b6000611cbd82611342565b915060008203611cd057611ccf611908565b5b600182039050919050565b600081905092915050565b50565b6000611cf6600083611cdb565b9150611d0182611ce6565b600082019050919050565b6000611d1782611ce9565b9150819050919050565b600082825260208201905092915050565b7f4661696c656420746f2073656e6420457468657220746f2066756e6465720000600082015250565b6000611d68601e83611d21565b9150611d7382611d32565b602082019050919050565b60006020820190508181036000830152611d9781611d5b565b9050919050565b6000819050919050565b6000611dc3611dbe611db9846111d5565b611d9e565b6111d5565b9050919050565b6000611dd582611da8565b9050919050565b6000611de782611dca565b9050919050565b611df781611ddc565b82525050565b611e068161148e565b82525050565b600082825260208201905092915050565b6000819050919050565b60008160070b9050919050565b611e3d81611e27565b8114611e4857600080fd5b50565b600081359050611e5a81611e34565b92915050565b6000611e6f6020840184611e4b565b905092915050565b611e8081611e27565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611eb257611eb1611e90565b5b83810192508235915060208301925067ffffffffffffffff821115611eda57611ed9611e86565b5b602082023603831315611ef057611eef611e8b565b5b509250929050565b600082825260208201905092915050565b6000819050919050565b60008083356001602003843603038112611f3057611f2f611e90565b5b83810192508235915060208301925067ffffffffffffffff821115611f5857611f57611e86565b5b600182023603831315611f6e57611f6d611e8b565b5b509250929050565b82818337600083830152505050565b6000611f9183856112bd565b9350611f9e838584611f76565b611fa7836112f8565b840190509392505050565b600081359050611fc181611b1c565b92915050565b6000611fd66020840184611fb2565b905092915050565b600060408301611ff16000840184611f13565b8583036000870152612004838284611f85565b925050506120156020840184611fc7565b612022602086018261134c565b508091505092915050565b60006120398383611fde565b905092915050565b60008235600160400383360303811261205d5761205c611e90565b5b82810191505092915050565b6000602082019050919050565b60006120828385611ef8565b93508360208402850161209484611f09565b8060005b878110156120d85784840389526120af8284612041565b6120b9858261202d565b94506120c483612069565b925060208a01995050600181019050612098565b50829750879450505050509392505050565b6000604083016120fd6000840184611e60565b61210a6000860182611e77565b506121186020840184611e95565b858303602087015261212b838284612076565b925050508091505092915050565b600061214583836120ea565b905092915050565b60008235600160400383360303811261216957612168611e90565b5b82810191505092915050565b6000602082019050919050565b600061218e8385611e0c565b9350836020840285016121a084611e1d565b8060005b878110156121e45784840389526121bb828461214d565b6121c58582612139565b94506121d083612175565b925060208a019950506001810190506121a4565b50829750879450505050509392505050565b600060a08201905061220b600083018a611dee565b612218602083018961197f565b6122256040830188611dfd565b8181036060830152612238818688612182565b9050818103608083015261224d818486612182565b905098975050505050505050565b60008151905061226a8161153f565b92915050565b600060208284031215612286576122856111cb565b5b60006122948482850161225b565b91505092915050565b7f56657374696e6743616c6c65723a2063726561746520636c61776261636b207660008201527f657374696e67206163636f756e74206661696c65640000000000000000000000602082015250565b60006122f9603583611d21565b91506123048261229d565b604082019050919050565b60006020820190508181036000830152612328816122ec565b9050919050565b6000602082019050612344600083018461197f565b92915050565b600080600060608486031215612363576123626111cb565b5b600084015167ffffffffffffffff811115612381576123806111d0565b5b61238d86828701611c3b565b935050602084015167ffffffffffffffff8111156123ae576123ad6111d0565b5b6123ba86828701611c3b565b925050604084015167ffffffffffffffff8111156123db576123da6111d0565b5b6123e786828701611c3b565b9150509250925092565b600060a082019050612406600083018a61197f565b612413602083018961197f565b6124206040830188611dfd565b8181036060830152612433818688612182565b90508181036080830152612448818486612182565b905098975050505050505050565b7f56657374696e6743616c6c65723a20636f6e7665727420746f20636c6177626160008201527f636b2076657374696e67206163636f756e74206661696c656400000000000000602082015250565b60006124b2603983611d21565b91506124bd82612456565b604082019050919050565b600060208201905081810360008301526124e1816124a5565b9050919050565b6124f181611533565b82525050565b600060608201905061250c600083018661197f565b612519602083018561197f565b61252660408301846124e8565b949350505050565b7f56657374696e6743616c6c65723a2063726561746520636c61776261636b207660008201527f657374696e67206163636f756e7420666f7220636f6e7472616374206661696c60208201527f6564000000000000000000000000000000000000000000000000000000000000604082015250565b60006125b0604283611d21565b91506125bb8261252e565b606082019050919050565b600060208201905081810360008301526125df816125a3565b9050919050565b7f7265766572742068657265000000000000000000000000000000000000000000600082015250565b600061261c600b83611d21565b9150612627826125e6565b602082019050919050565b6000602082019050818103600083015261264b8161260f565b9050919050565b7f56657374696e6743616c6c65723a207570646174652076657374696e6720667560008201527f6e646572206661696c6564000000000000000000000000000000000000000000602082015250565b60006126ae602b83611d21565b91506126b982612652565b604082019050919050565b600060208201905081810360008301526126dd816126a1565b9050919050565b7f4661696c656420746f2073656e6420457468657220746f2064656c656761746f60008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000612740602183611d21565b915061274b826126e4565b604082019050919050565b6000602082019050818103600083015261276f81612733565b905091905056fea26469706673582212204b37cada22f7b3efcbd3cfcf736d8690d85031d8077a13c463c51a43f0b3f3cf64736f6c63430008130033",
+  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c80636c49d3031161008c5780638e292e40116100665780638e292e40146101fe5780639cfef1291461022e578063cdb501751461024a578063fc9c1a8714610266576100cf565b80636c49d303146101a857806372e7c9ab146101c45780637caef81b146101f4576100cf565b806303f4be50146100d45780631e9178bb1461010457806327e235e3146101205780634fe1a8df146101525780635a2110641461016e57806361bc221a1461018a575b600080fd5b6100ee60048036038101906100e99190611233565b610296565b6040516100fb919061142e565b60405180910390f35b61011e6004803603810190610119919061156b565b61041c565b005b61013a60048036038101906101359190611662565b61068f565b6040516101499392919061168f565b60405180910390f35b61016c600480360381019061016791906116db565b610722565b005b61018860048036038101906101839190611662565b610828565b005b6101926108ee565b60405161019f91906117a6565b60405180910390f35b6101c260048036038101906101bd91906116db565b6108f4565b005b6101de60048036038101906101d99190611233565b610ac0565b6040516101eb919061142e565b60405180910390f35b6101fc610b80565b005b610218600480360381019061021391906117c1565b610c4a565b604051610225919061142e565b60405180910390f35b61024860048036038101906102439190611233565b610d94565b005b610264600480360381019061025f9190611828565b610e60565b005b610280600480360381019061027b919061187b565b610f2c565b60405161028d919061142e565b60405180910390f35b606060008290508073ffffffffffffffffffffffffffffffffffffffff16634f2be91f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102e557600080fd5b505af11580156102f9573d6000803e3d6000fd5b5050505060008081548092919061030f90611937565b919050555061080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8686866040518463ffffffff1660e01b81526004016103539392919061198e565b6000604051808303816000875af1158015610372573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061039b9190611c69565b91508073ffffffffffffffffffffffffffffffffffffffff16636deebae36040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156103e557600080fd5b505af11580156103f9573d6000803e3d6000fd5b5050505060008081548092919061040f90611cb2565b9190505550509392505050565b81156104e85760008081548092919061043490611937565b919050555060008873ffffffffffffffffffffffffffffffffffffffff16600f60405161046090611d0c565b60006040518083038185875af1925050503d806000811461049d576040519150601f19603f3d011682016040523d82523d6000602084013e6104a2565b606091505b50509050806104e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104dd90611d7e565b60405180910390fd5b505b600061080373ffffffffffffffffffffffffffffffffffffffff16634fe1a8df8c8c8b8b8b8b8b6040518863ffffffff1660e01b815260040161053197969594939291906121f6565b6020604051808303816000875af1158015610550573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105749190612270565b9050806105b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ad9061230f565b60405180910390fd5b81156106825760008973ffffffffffffffffffffffffffffffffffffffff16600f6040516105e390611d0c565b60006040518083038185875af1925050503d8060008114610620576040519150601f19603f3d011682016040523d82523d6000602084013e610625565b606091505b5050905080610669576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066090611d7e565b60405180910390fd5b60008081548092919061067b90611937565b9190505550505b5050505050505050505050565b606080606061080373ffffffffffffffffffffffffffffffffffffffff166327e235e3856040518263ffffffff1660e01b81526004016106cf919061232f565b600060405180830381865afa1580156106ec573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610715919061234a565b9250925092509193909250565b60008081548092919061073490611937565b9190505550600061080373ffffffffffffffffffffffffffffffffffffffff16634fe1a8df898989898989896040518863ffffffff1660e01b815260040161078297969594939291906123f1565b6020604051808303816000875af11580156107a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c59190612270565b905080610807576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fe9061230f565b60405180910390fd5b60008081548092919061081990611cb2565b91905055505050505050505050565b600061080373ffffffffffffffffffffffffffffffffffffffff16635a211064836040518263ffffffff1660e01b8152600401610865919061232f565b6020604051808303816000875af1158015610884573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a89190612270565b9050806108ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906124c8565b60405180910390fd5b5050565b60005481565b60008790508073ffffffffffffffffffffffffffffffffffffffff16634f2be91f6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b5050505060008081548092919061096b90611937565b9190505550600061080373ffffffffffffffffffffffffffffffffffffffff16634fe1a8df8a8a8a8a8a8a8a6040518863ffffffff1660e01b81526004016109b997969594939291906123f1565b6020604051808303816000875af11580156109d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fc9190612270565b905080610a3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a359061230f565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16636deebae36040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a8657600080fd5b505af1158015610a9a573d6000803e3d6000fd5b50505050600080815480929190610ab090611cb2565b9190505550505050505050505050565b6060600080815480929190610ad490611937565b919050555061080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8585856040518463ffffffff1660e01b8152600401610b189392919061198e565b6000604051808303816000875af1158015610b37573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610b609190611c69565b9050600080815480929190610b7490611cb2565b91905055509392505050565b600061080373ffffffffffffffffffffffffffffffffffffffff1663cdb50175333060006040518463ffffffff1660e01b8152600401610bc2939291906124f7565b6020604051808303816000875af1158015610be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c059190612270565b905080610c47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3e906125c6565b60405180910390fd5b50565b6060600080815480929190610c5e90611937565b919050555061080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8686866040518463ffffffff1660e01b8152600401610ca29392919061198e565b6000604051808303816000875af1158015610cc1573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610cea9190611c69565b90508115610d34576000610d33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2a90612632565b60405180910390fd5b5b600080815480929190610d4690611cb2565b91905055506000610d8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8390612632565b60405180910390fd5b949350505050565b600061080373ffffffffffffffffffffffffffffffffffffffff16639cfef1298585856040518463ffffffff1660e01b8152600401610dd59392919061198e565b6020604051808303816000875af1158015610df4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e189190612270565b905080610e5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e51906126c4565b60405180910390fd5b50505050565b600061080373ffffffffffffffffffffffffffffffffffffffff1663cdb501758585856040518463ffffffff1660e01b8152600401610ea1939291906124f7565b6020604051808303816000875af1158015610ec0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee49190612270565b905080610f26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1d9061230f565b60405180910390fd5b50505050565b6060821561102e57600080815480929190610f4690611937565b91905055503073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161461102d5760008473ffffffffffffffffffffffffffffffffffffffff16600f604051610fa590611d0c565b60006040518083038185875af1925050503d8060008114610fe2576040519150601f19603f3d011682016040523d82523d6000602084013e610fe7565b606091505b505090508061102b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102290612756565b60405180910390fd5b505b5b61080373ffffffffffffffffffffffffffffffffffffffff166372e7c9ab8888886040518463ffffffff1660e01b815260040161106d9392919061198e565b6000604051808303816000875af115801561108c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906110b59190611c69565b905081156111b7576000808154809291906110cf90611937565b91905055503073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146111b65760008473ffffffffffffffffffffffffffffffffffffffff16600f60405161112e90611d0c565b60006040518083038185875af1925050503d806000811461116b576040519150601f19603f3d011682016040523d82523d6000602084013e611170565b606091505b50509050806111b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ab90612756565b60405180910390fd5b505b5b9695505050505050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611200826111d5565b9050919050565b611210816111f5565b811461121b57600080fd5b50565b60008135905061122d81611207565b92915050565b60008060006060848603121561124c5761124b6111cb565b5b600061125a8682870161121e565b935050602061126b8682870161121e565b925050604061127c8682870161121e565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b838110156112ec5780820151818401526020810190506112d1565b60008484015250505050565b6000601f19601f8301169050919050565b6000611314826112b2565b61131e81856112bd565b935061132e8185602086016112ce565b611337816112f8565b840191505092915050565b6000819050919050565b61135581611342565b82525050565b600060408301600083015184820360008601526113788282611309565b915050602083015161138d602086018261134c565b508091505092915050565b60006113a4838361135b565b905092915050565b6000602082019050919050565b60006113c482611286565b6113ce8185611291565b9350836020820285016113e0856112a2565b8060005b8581101561141c57848403895281516113fd8582611398565b9450611408836113ac565b925060208a019950506001810190506113e4565b50829750879550505050505092915050565b6000602082019050818103600083015261144881846113b9565b905092915050565b600061145b826111d5565b9050919050565b61146b81611450565b811461147657600080fd5b50565b60008135905061148881611462565b92915050565b600067ffffffffffffffff82169050919050565b6114ab8161148e565b81146114b657600080fd5b50565b6000813590506114c8816114a2565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126114f3576114f26114ce565b5b8235905067ffffffffffffffff8111156115105761150f6114d3565b5b60208301915083602082028301111561152c5761152b6114d8565b5b9250929050565b60008115159050919050565b61154881611533565b811461155357600080fd5b50565b6000813590506115658161153f565b92915050565b6000806000806000806000806000806101008b8d03121561158f5761158e6111cb565b5b600061159d8d828e01611479565b9a505060206115ae8d828e0161121e565b99505060406115bf8d828e01611479565b98505060606115d08d828e016114b9565b97505060808b013567ffffffffffffffff8111156115f1576115f06111d0565b5b6115fd8d828e016114dd565b965096505060a08b013567ffffffffffffffff8111156116205761161f6111d0565b5b61162c8d828e016114dd565b945094505060c061163f8d828e01611556565b92505060e06116508d828e01611556565b9150509295989b9194979a5092959850565b600060208284031215611678576116776111cb565b5b60006116868482850161121e565b91505092915050565b600060608201905081810360008301526116a981866113b9565b905081810360208301526116bd81856113b9565b905081810360408301526116d181846113b9565b9050949350505050565b600080600080600080600060a0888a0312156116fa576116f96111cb565b5b60006117088a828b0161121e565b97505060206117198a828b0161121e565b965050604061172a8a828b016114b9565b955050606088013567ffffffffffffffff81111561174b5761174a6111d0565b5b6117578a828b016114dd565b9450945050608088013567ffffffffffffffff81111561177a576117796111d0565b5b6117868a828b016114dd565b925092505092959891949750929550565b6117a081611342565b82525050565b60006020820190506117bb6000830184611797565b92915050565b600080600080608085870312156117db576117da6111cb565b5b60006117e98782880161121e565b94505060206117fa8782880161121e565b935050604061180b8782880161121e565b925050606061181c87828801611556565b91505092959194509250565b600080600060608486031215611841576118406111cb565b5b600061184f8682870161121e565b93505060206118608682870161121e565b925050604061187186828701611556565b9150509250925092565b60008060008060008060c08789031215611898576118976111cb565b5b60006118a689828a0161121e565b96505060206118b789828a0161121e565b95505060406118c889828a0161121e565b94505060606118d989828a01611479565b93505060806118ea89828a01611556565b92505060a06118fb89828a01611556565b9150509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061194282611342565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361197457611973611908565b5b600182019050919050565b611988816111f5565b82525050565b60006060820190506119a3600083018661197f565b6119b0602083018561197f565b6119bd604083018461197f565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6119fd826112f8565b810181811067ffffffffffffffff82111715611a1c57611a1b6119c5565b5b80604052505050565b6000611a2f6111c1565b9050611a3b82826119f4565b919050565b600067ffffffffffffffff821115611a5b57611a5a6119c5565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff821115611a9657611a956119c5565b5b611a9f826112f8565b9050602081019050919050565b6000611abf611aba84611a7b565b611a25565b905082815260208101848484011115611adb57611ada611a76565b5b611ae68482856112ce565b509392505050565b600082601f830112611b0357611b026114ce565b5b8151611b13848260208601611aac565b91505092915050565b611b2581611342565b8114611b3057600080fd5b50565b600081519050611b4281611b1c565b92915050565b600060408284031215611b5e57611b5d611a6c565b5b611b686040611a25565b9050600082015167ffffffffffffffff811115611b8857611b87611a71565b5b611b9484828501611aee565b6000830152506020611ba884828501611b33565b60208301525092915050565b6000611bc7611bc284611a40565b611a25565b90508083825260208201905060208402830185811115611bea57611be96114d8565b5b835b81811015611c3157805167ffffffffffffffff811115611c0f57611c0e6114ce565b5b808601611c1c8982611b48565b85526020850194505050602081019050611bec565b5050509392505050565b600082601f830112611c5057611c4f6114ce565b5b8151611c60848260208601611bb4565b91505092915050565b600060208284031215611c7f57611c7e6111cb565b5b600082015167ffffffffffffffff811115611c9d57611c9c6111d0565b5b611ca984828501611c3b565b91505092915050565b6000611cbd82611342565b915060008203611cd057611ccf611908565b5b600182039050919050565b600081905092915050565b50565b6000611cf6600083611cdb565b9150611d0182611ce6565b600082019050919050565b6000611d1782611ce9565b9150819050919050565b600082825260208201905092915050565b7f4661696c656420746f2073656e6420457468657220746f2066756e6465720000600082015250565b6000611d68601e83611d21565b9150611d7382611d32565b602082019050919050565b60006020820190508181036000830152611d9781611d5b565b9050919050565b6000819050919050565b6000611dc3611dbe611db9846111d5565b611d9e565b6111d5565b9050919050565b6000611dd582611da8565b9050919050565b6000611de782611dca565b9050919050565b611df781611ddc565b82525050565b611e068161148e565b82525050565b600082825260208201905092915050565b6000819050919050565b60008160070b9050919050565b611e3d81611e27565b8114611e4857600080fd5b50565b600081359050611e5a81611e34565b92915050565b6000611e6f6020840184611e4b565b905092915050565b611e8081611e27565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611eb257611eb1611e90565b5b83810192508235915060208301925067ffffffffffffffff821115611eda57611ed9611e86565b5b602082023603831315611ef057611eef611e8b565b5b509250929050565b600082825260208201905092915050565b6000819050919050565b60008083356001602003843603038112611f3057611f2f611e90565b5b83810192508235915060208301925067ffffffffffffffff821115611f5857611f57611e86565b5b600182023603831315611f6e57611f6d611e8b565b5b509250929050565b82818337600083830152505050565b6000611f9183856112bd565b9350611f9e838584611f76565b611fa7836112f8565b840190509392505050565b600081359050611fc181611b1c565b92915050565b6000611fd66020840184611fb2565b905092915050565b600060408301611ff16000840184611f13565b8583036000870152612004838284611f85565b925050506120156020840184611fc7565b612022602086018261134c565b508091505092915050565b60006120398383611fde565b905092915050565b60008235600160400383360303811261205d5761205c611e90565b5b82810191505092915050565b6000602082019050919050565b60006120828385611ef8565b93508360208402850161209484611f09565b8060005b878110156120d85784840389526120af8284612041565b6120b9858261202d565b94506120c483612069565b925060208a01995050600181019050612098565b50829750879450505050509392505050565b6000604083016120fd6000840184611e60565b61210a6000860182611e77565b506121186020840184611e95565b858303602087015261212b838284612076565b925050508091505092915050565b600061214583836120ea565b905092915050565b60008235600160400383360303811261216957612168611e90565b5b82810191505092915050565b6000602082019050919050565b600061218e8385611e0c565b9350836020840285016121a084611e1d565b8060005b878110156121e45784840389526121bb828461214d565b6121c58582612139565b94506121d083612175565b925060208a019950506001810190506121a4565b50829750879450505050509392505050565b600060a08201905061220b600083018a611dee565b612218602083018961197f565b6122256040830188611dfd565b8181036060830152612238818688612182565b9050818103608083015261224d818486612182565b905098975050505050505050565b60008151905061226a8161153f565b92915050565b600060208284031215612286576122856111cb565b5b60006122948482850161225b565b91505092915050565b7f56657374696e6743616c6c65723a2063726561746520636c61776261636b207660008201527f657374696e67206163636f756e74206661696c65640000000000000000000000602082015250565b60006122f9603583611d21565b91506123048261229d565b604082019050919050565b60006020820190508181036000830152612328816122ec565b9050919050565b6000602082019050612344600083018461197f565b92915050565b600080600060608486031215612363576123626111cb565b5b600084015167ffffffffffffffff811115612381576123806111d0565b5b61238d86828701611c3b565b935050602084015167ffffffffffffffff8111156123ae576123ad6111d0565b5b6123ba86828701611c3b565b925050604084015167ffffffffffffffff8111156123db576123da6111d0565b5b6123e786828701611c3b565b9150509250925092565b600060a082019050612406600083018a61197f565b612413602083018961197f565b6124206040830188611dfd565b8181036060830152612433818688612182565b90508181036080830152612448818486612182565b905098975050505050505050565b7f56657374696e6743616c6c65723a20636f6e7665727420746f20636c6177626160008201527f636b2076657374696e67206163636f756e74206661696c656400000000000000602082015250565b60006124b2603983611d21565b91506124bd82612456565b604082019050919050565b600060208201905081810360008301526124e1816124a5565b9050919050565b6124f181611533565b82525050565b600060608201905061250c600083018661197f565b612519602083018561197f565b61252660408301846124e8565b949350505050565b7f56657374696e6743616c6c65723a2063726561746520636c61776261636b207660008201527f657374696e67206163636f756e7420666f7220636f6e7472616374206661696c60208201527f6564000000000000000000000000000000000000000000000000000000000000604082015250565b60006125b0604283611d21565b91506125bb8261252e565b606082019050919050565b600060208201905081810360008301526125df816125a3565b9050919050565b7f7265766572742068657265000000000000000000000000000000000000000000600082015250565b600061261c600b83611d21565b9150612627826125e6565b602082019050919050565b6000602082019050818103600083015261264b8161260f565b9050919050565b7f56657374696e6743616c6c65723a207570646174652076657374696e6720667560008201527f6e646572206661696c6564000000000000000000000000000000000000000000602082015250565b60006126ae602b83611d21565b91506126b982612652565b604082019050919050565b600060208201905081810360008301526126dd816126a1565b9050919050565b7f4661696c656420746f2073656e6420457468657220746f2064656c656761746f60008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000612740602183611d21565b915061274b826126e4565b604082019050919050565b6000602082019050818103600083015261276f81612733565b905091905056fea26469706673582212204b37cada22f7b3efcbd3cfcf736d8690d85031d8077a13c463c51a43f0b3f3cf64736f6c63430008130033",
   "linkReferences": {},
   "deployedLinkReferences": {}
 }

programming_language: Swift
filename: VestingCaller.sol
change_type: ModificationType.MODIFY
diff: @@ -3,12 +3,15 @@ pragma solidity ^0.8.17;
 
 import "../../common/Types.sol";
 import "../VestingI.sol" as vesting;
+import "../../testutil/contracts/ICounter.sol";
 
 /// @title VestingCaller
 /// @author Evmos Core Team
 /// @dev This contract is used to test external contract calls to the vesting precompile.
 contract VestingCaller {
-
+    /// counter is used to test the state persistence bug, when EVM and Cosmos state were both
+    /// changed in the same function.
+    uint256 public counter;
     /// @dev Defines a method to test creating a new clawback vesting account.
     /// @param funder The address of the account that will fund the vesting account.
     /// @param to The address of the account that will receive the vesting account.
@@ -23,7 +26,10 @@ contract VestingCaller {
             to,
             enableGovClawback
         );
-        require(success, "VestingCaller: create clawback vesting account failed");
+        require(
+            success,
+            "VestingCaller: create clawback vesting account failed"
+        );
     }
 
     /// @dev Defines a method to test funding a vesting account
@@ -39,6 +45,49 @@ contract VestingCaller {
         vesting.Period[] calldata lockupPeriods,
         vesting.Period[] calldata vestingPeriods
     ) public {
+        counter++;
+        bool success = vesting.VESTING_CONTRACT.fundVestingAccount(
+            funder,
+            to,
+            startTime,
+            lockupPeriods,
+            vestingPeriods
+        );
+        require(
+            success,
+            "VestingCaller: create clawback vesting account failed"
+        );
+        counter--;
+    }
+
+    /// @dev Defines a method to test funding a vesting account.
+    /// If specified, it sends 15 aevmos to the funder before and/or after
+    /// the precompile call
+    /// @param funder The address of the account that will fund the vesting account.
+    /// @param to The address of the account that will receive the vesting account.
+    /// @param _transferTo The address to send some funds to.
+    /// @param startTime The time at which the vesting account will start.
+    /// @param lockupPeriods The lockup periods of the vesting account.
+    /// @param vestingPeriods The vesting periods of the vesting account.
+    /// @param transferBefore A boolean to specify if the contract should transfer
+    /// funds to the funder before the precompile call.
+    /// @param transferAfter A boolean to specify if the contract should transfer
+    /// funds to the funder after the precompile call.
+    function fundVestingAccountAndTransfer(
+        address payable funder,
+        address to,
+        address payable _transferTo,
+        uint64 startTime,
+        vesting.Period[] calldata lockupPeriods,
+        vesting.Period[] calldata vestingPeriods,
+        bool transferBefore,
+        bool transferAfter
+    ) public {
+        if (transferBefore) {
+            counter++;
+            (bool sent, ) = _transferTo.call{value: 15}("");
+            require(sent, "Failed to send Ether to funder");
+        }
         bool success = vesting.VESTING_CONTRACT.fundVestingAccount(
             funder,
             to,
@@ -46,7 +95,46 @@ contract VestingCaller {
             lockupPeriods,
             vestingPeriods
         );
-        require(success, "VestingCaller: create clawback vesting account failed");
+        require(
+            success,
+            "VestingCaller: create clawback vesting account failed"
+        );
+        if (transferAfter) {
+            (bool sent, ) = _transferTo.call{value: 15}("");
+            require(sent, "Failed to send Ether to funder");
+            counter++;
+        }
+    }
+
+    /// @dev Defines a method to test funding a vesting account
+    /// @param funder The address of the Counter contract that will fund the vesting account.
+    /// @param to The address of the account that will receive the vesting account.
+    /// @param startTime The time at which the vesting account will start.
+    /// @param lockupPeriods The lockup periods of the vesting account.
+    /// @param vestingPeriods The vesting periods of the vesting account.
+    function fundVestingAccountWithCounterContract(
+        address funder,
+        address to,
+        uint64 startTime,
+        vesting.Period[] calldata lockupPeriods,
+        vesting.Period[] calldata vestingPeriods
+    ) public {
+        ICounter counterContract = ICounter(funder);
+        counterContract.add();
+        counter++;
+        bool success = vesting.VESTING_CONTRACT.fundVestingAccount(
+            funder,
+            to,
+            startTime,
+            lockupPeriods,
+            vestingPeriods
+        );
+        require(
+            success,
+            "VestingCaller: create clawback vesting account failed"
+        );
+        counterContract.subtract();
+        counter--;
     }
 
     /// @dev Defines a method to test clawing back coins from a vesting account.
@@ -59,7 +147,86 @@ contract VestingCaller {
         address account,
         address dest
     ) public returns (Coin[] memory coins) {
-        return vesting.VESTING_CONTRACT.clawback(funder, account, dest);
+        counter++;
+        coins = vesting.VESTING_CONTRACT.clawback(funder, account, dest);
+        counter--;
+        return coins;
+    }
+
+    /// @dev Defines a method to test clawing back coins from a vesting account.
+    /// @param funder The address of the account that funded the vesting account.
+    /// @param account The address of the vesting account.
+    /// @param dest The address of the account that will receive the clawed back coins.
+    /// @param _transferTo The address to send some funds to.
+    /// @param _before Boolean to specify if funds should be transferred to _transferTo before the precompile call
+    /// @param _after Boolean to specify if funds should be transferred to _transferTo after the precompile call    
+    /// @return coins The coins that were clawed back from the vesting account.
+    function clawbackWithTransfer(
+        address funder,
+        address account,
+        address dest,
+        address payable _transferTo,
+        bool _before,
+        bool _after
+    ) public returns (Coin[] memory coins) {
+        if (_before) {
+            counter++;
+            if (dest != address(this)) {
+                (bool sent, ) = _transferTo.call{value: 15}("");
+                require(sent, "Failed to send Ether to delegator");
+            }
+        }
+        coins = vesting.VESTING_CONTRACT.clawback(funder, account, dest);
+        if (_after) {
+            counter++;
+            if (dest != address(this)) {
+                (bool sent, ) = _transferTo.call{value: 15}("");
+                require(sent, "Failed to send Ether to delegator");
+            }
+        }
+        return coins;
+    }
+
+    /// @dev Defines a method to test clawing back coins from a vesting account.
+    /// It is used for testing the state revert.
+    /// @param funder The address of the account that funded the vesting account.
+    /// @param account The address of the vesting account.
+    /// @param dest The address of the account that will receive the clawed back coins.
+    /// @param before Boolean to specify if should revert before counter change.
+    /// @return coins The coins that were clawed back from the vesting account.
+    function clawbackWithRevert(
+        address funder,
+        address account,
+        address dest,
+        bool before
+    ) public returns (Coin[] memory coins) {
+        counter++;
+        coins = vesting.VESTING_CONTRACT.clawback(funder, account, dest);
+        if (before) {
+            require(false, "revert here");
+        }
+        counter--;
+        require(false, "revert here");
+        return coins;
+    }
+
+    /// @dev Defines a method to test clawing back coins from a vesting account.
+    /// @param funder The address of the account that funded the vesting account.
+    /// @param account The address of the vesting account.
+    /// @param dest The address of the Counter smart contract that will receive the clawed back coins.
+    /// @return coins The coins that were clawed back from the vesting account.
+    function clawbackWithCounterCall(
+        address funder,
+        address account,
+        address dest
+    ) public returns (Coin[] memory coins) {
+        ICounter counterContract = ICounter(dest);
+        counterContract.add();
+        counter++;
+        coins = vesting.VESTING_CONTRACT.clawback(funder, account, dest);
+        counterContract.subtract();
+        counter--;
+        return coins;
     }
 
     /// @dev Defines a method to test updating the funder of a vesting account.
@@ -71,32 +238,52 @@ contract VestingCaller {
         address newFunder,
         address vestingAddr
     ) public {
-        bool success = vesting.VESTING_CONTRACT.updateVestingFunder(funder, newFunder, vestingAddr);
+        bool success = vesting.VESTING_CONTRACT.updateVestingFunder(
+            funder,
+            newFunder,
+            vestingAddr
+        );
         require(success, "VestingCaller: update vesting funder failed");
     }
 
     /// @dev Defines a method to test converting a vesting account to a clawback vesting account.
     /// @param vestingAddr The address of the vesting account.
-    function convertVestingAccount(
-        address vestingAddr
-    ) public {
-        bool success = vesting.VESTING_CONTRACT.convertVestingAccount(vestingAddr);
-        require(success, "VestingCaller: convert to clawback vesting account failed");
+    function convertVestingAccount(address vestingAddr) public {
+        bool success = vesting.VESTING_CONTRACT.convertVestingAccount(
+            vestingAddr
+        );
+        require(
+            success,
+            "VestingCaller: convert to clawback vesting account failed"
+        );
     }
 
     /// @dev Converts a smart contract address to a vesting account on top of it being a smart contract
     function createClawbackVestingAccountForContract() public {
-        bool success = vesting.VESTING_CONTRACT.createClawbackVestingAccount(msg.sender, address(this), false);
-        require(success, "VestingCaller: create clawback vesting account for contract failed");
+        bool success = vesting.VESTING_CONTRACT.createClawbackVestingAccount(
+            msg.sender,
+            address(this),
+            false
+        );
+        require(
+            success,
+            "VestingCaller: create clawback vesting account for contract failed"
+        );
     }
 
     /// @dev Defines a method to test getting the balances of a vesting account.
     /// @param vestingAddr The address of the vesting account.
-    function balances(address vestingAddr) public view returns (
-        Coin[] memory locked, 
-        Coin[] memory unvested, 
-        Coin[] memory vested
-    ) {
+    function balances(
+        address vestingAddr
+    )
+        public
+        view
+        returns (
+            Coin[] memory locked,
+            Coin[] memory unvested,
+            Coin[] memory vested
+        )
+    {
         return vesting.VESTING_CONTRACT.balances(vestingAddr);
     }
 }

programming_language: Go
filename: tx.go
change_type: ModificationType.MODIFY
diff: @@ -6,10 +6,14 @@ import (
 	"fmt"
 
 	sdk "github.com/cosmos/cosmos-sdk/types"
+
 	"github.com/ethereum/go-ethereum/accounts/abi"
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core/vm"
+
 	"github.com/evmos/evmos/v18/precompiles/authorization"
+	cmn "github.com/evmos/evmos/v18/precompiles/common"
+	"github.com/evmos/evmos/v18/utils"
 )
 
 const (
@@ -27,7 +31,7 @@ const (
 )
 
 // CreateClawbackVestingAccount creates a new clawback vesting account
-func (p Precompile) CreateClawbackVestingAccount(
+func (p *Precompile) CreateClawbackVestingAccount(
 	ctx sdk.Context,
 	origin common.Address,
 	stateDB vm.StateDB,
@@ -39,6 +43,7 @@ func (p Precompile) CreateClawbackVestingAccount(
 		return nil, err
 	}
 
+	// Only EOA can be vesting accounts
 	// Check if the origin matches the vesting address
 	if origin != vestingAddr {
 		return nil, fmt.Errorf(ErrDifferentFromOrigin, origin, vestingAddr)
@@ -63,7 +68,7 @@ func (p Precompile) CreateClawbackVestingAccount(
 }
 
 // FundVestingAccount funds a vesting account by creating vesting schedules
-func (p Precompile) FundVestingAccount(
+func (p *Precompile) FundVestingAccount(
 	ctx sdk.Context,
 	contract *vm.Contract,
 	origin common.Address,
@@ -76,8 +81,12 @@ func (p Precompile) FundVestingAccount(
 		return nil, err
 	}
 
-	// if caller address is origin, the funder MUST match the origin
-	if contract.CallerAddress == origin && origin != funderAddr {
+	isContractCaller := contract.CallerAddress != origin
+
+	// funder can only be the origin or the contract.Caller
+	isContractFunder := contract.CallerAddress == funderAddr && isContractCaller
+
+	if !isContractFunder && origin != funderAddr {
 		return nil, fmt.Errorf(ErrDifferentFromOrigin, origin, funderAddr)
 	}
 
@@ -90,11 +99,15 @@ func (p Precompile) FundVestingAccount(
 		),
 	)
 
-	if contract.CallerAddress != origin {
-		// check if authorization exists
-		_, _, err := authorization.CheckAuthzExists(ctx, p.AuthzKeeper, contract.CallerAddress, origin, FundVestingAccountMsgURL)
+	// in case the contract is the funder
+	// don't check for auth.
+	// The smart contract (funder) should handle who is authorized to make this call
+	if isContractCaller && !isContractFunder {
+		// if calling from a contract and the contract is not the funder (origin == funderAddr)
+		// check that an authorization exists
+		_, _, err := authorization.CheckAuthzExists(ctx, p.AuthzKeeper, contract.CallerAddress, funderAddr, FundVestingAccountMsgURL)
 		if err != nil {
-			return nil, fmt.Errorf(authorization.ErrAuthzDoesNotExistOrExpired, contract.CallerAddress, origin)
+			return nil, fmt.Errorf(authorization.ErrAuthzDoesNotExistOrExpired, FundVestingAccountMsgURL, contract.CallerAddress)
 		}
 	}
 
@@ -103,6 +116,21 @@ func (p Precompile) FundVestingAccount(
 		return nil, err
 	}
 
+	if isContractCaller {
+		vestingCoins := msg.VestingPeriods.TotalAmount()
+		lockedUpCoins := msg.LockupPeriods.TotalAmount()
+		if vestingCoins.IsZero() && lockedUpCoins.IsAllPositive() {
+			vestingCoins = lockedUpCoins
+		}
+
+		// NOTE: This ensures that the changes in the bank keeper are correctly mirrored to the EVM stateDB.
+		amt := vestingCoins.AmountOf(utils.BaseDenom).BigInt()
+		p.SetBalanceChangeEntries(
+			cmn.NewBalanceChangeEntry(funderAddr, amt, cmn.Sub),
+			cmn.NewBalanceChangeEntry(vestingAddr, amt, cmn.Add),
+		)
+	}
+
 	if err = p.EmitFundVestingAccountEvent(ctx, stateDB, msg, funderAddr, vestingAddr, lockupPeriods, vestingPeriods); err != nil {
 		return nil, err
 	}
@@ -111,7 +139,7 @@ func (p Precompile) FundVestingAccount(
 }
 
 // Clawback clawbacks tokens from a clawback vesting account
-func (p Precompile) Clawback(
+func (p *Precompile) Clawback(
 	ctx sdk.Context,
 	contract *vm.Contract,
 	origin common.Address,
@@ -124,8 +152,13 @@ func (p Precompile) Clawback(
 		return nil, err
 	}
 
+	isContractCaller := contract.CallerAddress != origin
+
+	// funder can only be the origin or the contract.Caller
+	isContractFunder := contract.CallerAddress == funderAddr && isContractCaller
+
 	// if caller address is origin, the funder MUST match the origin
-	if contract.CallerAddress == origin && origin != funderAddr {
+	if !isContractFunder && origin != funderAddr {
 		return nil, fmt.Errorf(ErrDifferentFunderOrigin, origin, funderAddr)
 	}
 
@@ -138,11 +171,15 @@ func (p Precompile) Clawback(
 		),
 	)
 
-	if contract.CallerAddress != origin {
-		// check if authorization exists
-		_, _, err := authorization.CheckAuthzExists(ctx, p.AuthzKeeper, contract.CallerAddress, origin, ClawbackMsgURL)
+	// in case the contract is the funder
+	// don't check for auth.
+	// The smart contract (funder) should handle who is authorized to make this call
+	if isContractCaller && !isContractFunder {
+		// if calling from a contract and the contract is not the funder (origin == funderAddr)
+		// check that an authorization exists.
+		_, _, err := authorization.CheckAuthzExists(ctx, p.AuthzKeeper, contract.CallerAddress, funderAddr, ClawbackMsgURL)
 		if err != nil {
-			return nil, fmt.Errorf(authorization.ErrAuthzDoesNotExistOrExpired, contract.CallerAddress, origin)
+			return nil, fmt.Errorf(authorization.ErrAuthzDoesNotExistOrExpired, ClawbackMsgURL, contract.CallerAddress)
 		}
 	}
 
@@ -151,6 +188,16 @@ func (p Precompile) Clawback(
 		return nil, err
 	}
 
+	if isContractCaller {
+		// NOTE: This ensures that the changes in the bank keeper are correctly mirrored to the EVM stateDB when calling
+		// the precompile from another contract.
+		clawbackAmt := response.Coins.AmountOf(utils.BaseDenom).BigInt()
+		p.SetBalanceChangeEntries(
+			cmn.NewBalanceChangeEntry(accountAddr, clawbackAmt, cmn.Sub),
+			cmn.NewBalanceChangeEntry(destAddr, clawbackAmt, cmn.Add),
+		)
+	}
+
 	if err = p.EmitClawbackEvent(ctx, stateDB, funderAddr, accountAddr, destAddr); err != nil {
 		return nil, err
 	}
@@ -161,7 +208,7 @@ func (p Precompile) Clawback(
 }
 
 // UpdateVestingFunder updates the vesting funder of a clawback vesting account
-func (p Precompile) UpdateVestingFunder(
+func (p *Precompile) UpdateVestingFunder(
 	ctx sdk.Context,
 	contract *vm.Contract,
 	origin common.Address,
@@ -174,8 +221,11 @@ func (p Precompile) UpdateVestingFunder(
 		return nil, err
 	}
 
+	isContractCall := contract.CallerAddress != origin
+	isContractFunder := contract.CallerAddress == funderAddr && isContractCall
+	// only the funder can update the funder
 	// if caller address is origin, the funder MUST match the origin
-	if contract.CallerAddress == origin && origin != funderAddr {
+	if !isContractFunder && origin != funderAddr {
 		return nil, fmt.Errorf(ErrDifferentFunderOrigin, origin, funderAddr)
 	}
 
@@ -188,11 +238,15 @@ func (p Precompile) UpdateVestingFunder(
 		),
 	)
 
-	if contract.CallerAddress != origin {
-		// check if authorization exists
-		_, _, err := authorization.CheckAuthzExists(ctx, p.AuthzKeeper, contract.CallerAddress, origin, UpdateVestingFunderMsgURL)
+	// in case the contract is the funder
+	// don't check for auth.
+	// The smart contract (funder) should handle who is authorized to make this call
+	if isContractCall && !isContractFunder {
+		// if calling from a contract and the contract is not the funder (origin == funderAddr)
+		// check that an authorization exists
+		_, _, err := authorization.CheckAuthzExists(ctx, p.AuthzKeeper, contract.CallerAddress, funderAddr, UpdateVestingFunderMsgURL)
 		if err != nil {
-			return nil, fmt.Errorf(authorization.ErrAuthzDoesNotExistOrExpired, contract.CallerAddress, origin)
+			return nil, fmt.Errorf(authorization.ErrAuthzDoesNotExistOrExpired, UpdateVestingFunderMsgURL, contract.CallerAddress)
 		}
 	}
 
@@ -209,7 +263,7 @@ func (p Precompile) UpdateVestingFunder(
 }
 
 // ConvertVestingAccount converts a clawback vesting account to a base account once the vesting period is over.
-func (p Precompile) ConvertVestingAccount(
+func (p *Precompile) ConvertVestingAccount(
 	ctx sdk.Context,
 	stateDB vm.StateDB,
 	method *abi.Method,

programming_language: Go
filename: utils_test.go
change_type: ModificationType.MODIFY
diff: @@ -18,6 +18,7 @@ import (
 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
 	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
+	"github.com/ethereum/go-ethereum/accounts/abi"
 	"github.com/ethereum/go-ethereum/common"
 	ethtypes "github.com/ethereum/go-ethereum/core/types"
 	evmosapp "github.com/evmos/evmos/v18/app"
@@ -236,8 +237,8 @@ func (s *PrecompileTestSuite) BuildCallArgs(
 func (s *PrecompileTestSuite) FundTestClawbackVestingAccount() {
 	method := s.precompile.Methods[vesting.FundVestingAccountMethod]
 	createArgs := []interface{}{s.address, toAddr, uint64(time.Now().Unix()), lockupPeriods, vestingPeriods}
-	//nolint
 	msg, _, _, _, _, err := vesting.NewMsgFundVestingAccount(createArgs, &method)
+	s.Require().NoError(err)
 	_, err = s.app.VestingKeeper.FundVestingAccount(s.ctx, msg)
 	s.Require().NoError(err)
 	vestingAcc, err := s.app.VestingKeeper.Balances(s.ctx, &vestingtypes.QueryBalancesRequest{Address: sdk.AccAddress(toAddr.Bytes()).String()})
@@ -249,8 +250,8 @@ func (s *PrecompileTestSuite) FundTestClawbackVestingAccount() {
 // CreateTestClawbackVestingAccount creates a vesting account that can clawback
 func (s *PrecompileTestSuite) CreateTestClawbackVestingAccount(funder, vestingAddr common.Address) {
 	msgArgs := []interface{}{funder, vestingAddr, false}
-	//nolint
 	msg, _, _, err := vesting.NewMsgCreateClawbackVestingAccount(msgArgs)
+	s.Require().NoError(err)
 	err = evmosutil.FundAccount(s.ctx, s.app.BankKeeper, vestingAddr.Bytes(), sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(100))))
 	s.Require().NoError(err)
 	_, err = s.app.VestingKeeper.CreateClawbackVestingAccount(s.ctx, msg)
@@ -312,3 +313,23 @@ func (s *PrecompileTestSuite) NextBlock() {
 	s.ctx, err = evmosutil.CommitAndCreateNewCtx(s.ctx, s.app, time.Second, nil)
 	Expect(err).To(BeNil(), "failed to commit block")
 }
+
+// mergeEventMaps is a helper function to merge events maps from different contracts.
+// If duplicates events are present, map2 override map1 values.
+func mergeEventMaps(map1, map2 map[string]abi.Event) map[string]abi.Event {
+	// Create a new map to hold the merged result
+	mergedMap := make(map[string]abi.Event)
+
+	// Copy all key-value pairs from map1 to mergedMap
+	for k, v := range map1 {
+		mergedMap[k] = v
+	}
+
+	// Copy all key-value pairs from map2 to mergedMap
+	// If there are duplicate keys, values from map2 will overwrite those from map1
+	for k, v := range map2 {
+		mergedMap[k] = v
+	}
+
+	return mergedMap
+}

programming_language: Go