From 03f5b7e4b36584466f4404f0c798755d15bc3d37 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 7 May 2025 16:45:09 +0200 Subject: [PATCH 01/39] add: README for statebloat scenarios Includes the scenarios contemplated within statebloat as well as any extra data about them such as gas cost metrics. --- scenarios/statebloat/README.md | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 scenarios/statebloat/README.md diff --git a/scenarios/statebloat/README.md b/scenarios/statebloat/README.md new file mode 100644 index 00000000..28d23d77 --- /dev/null +++ b/scenarios/statebloat/README.md @@ -0,0 +1,35 @@ +# State Bloat Scenarios + +This directory contains scenarios designed to test different vectors of state growth on Ethereum. Each scenario focuses on a specific method of increasing the state size while minimizing ETH cost. + +## Available Scenarios + +1. `contract-deploy` - Deploys 24kB contracts (EIP-170 limit) +2. `delegate-flag` - Adds delegate flags to funded EOAs (EIP-7702) +3. `fund-eoa` - Funds fresh EOAs with minimal ETH +4. `empty-auth` - Creates EIP-7702 authorizations for empty addresses +5. `storage-slots` - Fills new storage slots in contracts + +## Testing + +These scenarios can be tested using Anvil (Foundry's local Ethereum node) or any other EVM-compatible testnet. For local testing: + +```bash +# Start Anvil +anvil + +# Run a scenario (example) +spamoor statebloat/contract-deploy [flags] +``` + +Each scenario directory contains its own README with specific configuration options and testing instructions. + +## Gas Efficiency Comparison + +| Rank | Scenario | Gas/Byte | Max Units in 30M Gas Block | +| ---- | --------------- | -------- | -------------------------- | +| 1 | Contract Deploy | ~202 | 6 deployments | +| 2 | Delegate Flag | ~232 | 960 tuples | +| 3 | Fund EOA | ~267 | 1000 accounts | +| 4 | Empty Auth | ~289 | 767 tuples | +| 5 | Storage Slots | 625 | 1500 slots | \ No newline at end of file From b50c7850a2dcdd5b4a1d3d6dca21c3af64a2c5f9 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 7 May 2025 16:46:09 +0200 Subject: [PATCH 02/39] add: Add first iteration over contract-deploy This scenario deploys contracts that are exactly 24kB in size (EIP-170 limit) to maximize state growth while minimizing gas cost. 1. Generates a contract with exactly 24,576 bytes of runtime code 2. Deploys the contract using CREATE 3. Each deployment adds: - 24,576 bytes of runtime code - Account trie node - Total state growth: ~24.7kB per deployment - 32,000 gas for CREATE - 20,000 gas for new account - 200 gas per byte for code deposit (24,576 bytes) - Total: 4,967,200 gas per deployment --- .../statebloat/contract-deploy/README.md | 80 ++ .../contract-deploy/contract/README.md | 35 + .../contract/StateBloatToken.abi | 1 + .../contract/StateBloatToken.bin | 1 + .../contract/StateBloatToken.go | 791 ++++++++++++++++++ .../contract/StateBloatToken.sol | 61 ++ .../contract-deploy/contract_deploy.go | 305 +++++++ 7 files changed, 1274 insertions(+) create mode 100644 scenarios/statebloat/contract-deploy/README.md create mode 100644 scenarios/statebloat/contract-deploy/contract/README.md create mode 100644 scenarios/statebloat/contract-deploy/contract/StateBloatToken.abi create mode 100644 scenarios/statebloat/contract-deploy/contract/StateBloatToken.bin create mode 100644 scenarios/statebloat/contract-deploy/contract/StateBloatToken.go create mode 100644 scenarios/statebloat/contract-deploy/contract/StateBloatToken.sol create mode 100644 scenarios/statebloat/contract-deploy/contract_deploy.go diff --git a/scenarios/statebloat/contract-deploy/README.md b/scenarios/statebloat/contract-deploy/README.md new file mode 100644 index 00000000..ecd830a7 --- /dev/null +++ b/scenarios/statebloat/contract-deploy/README.md @@ -0,0 +1,80 @@ +# Contract Deployment State Bloat + +This scenario deploys contracts that are exactly 24kB in size (EIP-170 limit) to maximize state growth while minimizing gas cost. + +## How it Works + +1. Generates a contract with exactly 24,576 bytes of runtime code +2. Deploys the contract using CREATE +3. Each deployment adds: + - 24,576 bytes of runtime code + - Account trie node + - Total state growth: ~24.7kB per deployment + +## Gas Cost Breakdown + +- 32,000 gas for CREATE +- 20,000 gas for new account +- 200 gas per byte for code deposit (24,576 bytes) +- Total: 4,967,200 gas per deployment + +## Usage + +```bash +spamoor statebloat/contract-deploy [flags] +``` + +### Configuration + +#### Base Settings (required) +- `--privkey` - Private key of the sending wallet +- `--rpchost` - RPC endpoint(s) to send transactions to + +#### Volume Control (either -c or -t required) +- `-c, --count` - Total number of contracts to deploy +- `-t, --throughput` - Contracts to deploy per slot +- `--max-pending` - Maximum number of pending deployments + +#### Transaction Settings +- `--basefee` - Max fee per gas in gwei (default: 20) +- `--tipfee` - Max tip per gas in gwei (default: 2) +- `--rebroadcast` - Seconds to wait before rebroadcasting (default: 120) + +#### Wallet Management +- `--max-wallets` - Maximum number of child wallets to use +- `--refill-amount` - ETH amount to fund each child wallet (default: 5) +- `--refill-balance` - Minimum ETH balance before refilling (default: 2) +- `--refill-interval` - Seconds between balance checks (default: 300) + +## Example + +Deploy 10 contracts: +```bash +spamoor statebloat/contract-deploy -p "" -h http://localhost:8545 -c 10 +``` + +Deploy 1 contract per slot: +```bash +spamoor statebloat/contract-deploy -p "" -h http://localhost:8545 -t 1 +``` + +## Testing with Anvil + +1. Start Anvil: +```bash +anvil +``` + +2. Run the scenario: +```bash +spamoor statebloat/contract-deploy -p "" -h http://localhost:8545 -c 1 +``` + +3. Verify state growth: +```bash +# Get the contract address from the deployment receipt +# Then check the code size +cast code --rpc-url http://localhost:8545 +``` + +The code size should be exactly 24,576 bytes. \ No newline at end of file diff --git a/scenarios/statebloat/contract-deploy/contract/README.md b/scenarios/statebloat/contract-deploy/contract/README.md new file mode 100644 index 00000000..de0d8758 --- /dev/null +++ b/scenarios/statebloat/contract-deploy/contract/README.md @@ -0,0 +1,35 @@ +# Contract Compilation + +This directory contains the Solidity contract and its compiled artifacts. To compile the contract and generate Go bindings: + +1. Install solc (Solidity compiler): +```bash +# On macOS +brew install solidity + +# On Ubuntu/Debian +sudo add-apt-repository ppa:ethereum/ethereum +sudo apt-get update +sudo apt-get install solc +``` + +2. Install abigen (ABI generator): +```bash +go install github.com/ethereum/go-ethereum/cmd/abigen@latest +``` + +3. Compile the contract: +```bash +solc --abi StateBloatToken.sol -o . --overwrite +solc --bin StateBloatToken.sol -o . --overwrite +``` + +4. Generate Go bindings: +```bash +abigen --bin=StateBloatToken.bin --abi=StateBloatToken.abi --pkg=contract --out=StateBloatToken.go +``` + +The generated files will be: +- `StateBloatToken.abi` - Contract ABI +- `StateBloatToken.bin` - Contract bytecode +- `StateBloatToken.go` - Go bindings \ No newline at end of file diff --git a/scenarios/statebloat/contract-deploy/contract/StateBloatToken.abi b/scenarios/statebloat/contract-deploy/contract/StateBloatToken.abi new file mode 100644 index 00000000..fb9e7b53 --- /dev/null +++ b/scenarios/statebloat/contract-deploy/contract/StateBloatToken.abi @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"uint256","name":"_salt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/scenarios/statebloat/contract-deploy/contract/StateBloatToken.bin b/scenarios/statebloat/contract-deploy/contract/StateBloatToken.bin new file mode 100644 index 00000000..0ea68c09 --- /dev/null +++ b/scenarios/statebloat/contract-deploy/contract/StateBloatToken.bin @@ -0,0 +1 @@ +60a060405234801561000f575f5ffd5b50604051611503380380611503833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b608051610dae6107555f395f6108cf0152610dae5ff3fe608060405234801561000f575f5ffd5b506004361061009c575f3560e01c806370a082311161006457806370a082311461015a57806395d89b411461018a578063a9059cbb146101a8578063bfa0b133146101d8578063dd62ed3e146101f65761009c565b806306fdde03146100a0578063095ea7b3146100be57806318160ddd146100ee57806323b872dd1461010c578063313ce5671461013c575b5f5ffd5b6100a8610226565b6040516100b59190610981565b60405180910390f35b6100d860048036038101906100d39190610a32565b6102b1565b6040516100e59190610a8a565b60405180910390f35b6100f661039e565b6040516101039190610ab2565b60405180910390f35b61012660048036038101906101219190610acb565b6103a4565b6040516101339190610a8a565b60405180910390f35b610144610684565b6040516101519190610b36565b60405180910390f35b610174600480360381019061016f9190610b4f565b610696565b6040516101819190610ab2565b60405180910390f35b6101926106ab565b60405161019f9190610981565b60405180910390f35b6101c260048036038101906101bd9190610a32565b610737565b6040516101cf9190610a8a565b60405180910390f35b6101e06108cd565b6040516101ed9190610ab2565b60405180910390f35b610210600480360381019061020b9190610b7a565b6108f1565b60405161021d9190610ab2565b60405180910390f35b5f805461023290610be5565b80601f016020809104026020016040519081016040528092919081815260200182805461025e90610be5565b80156102a95780601f10610280576101008083540402835291602001916102a9565b820191905f5260205f20905b81548152906001019060200180831161028c57829003601f168201915b505050505081565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161038c9190610ab2565b60405180910390a36001905092915050565b60035481565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041c90610c5f565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156104e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d790610cc7565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461052c9190610d12565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461057f9190610d45565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461060d9190610d12565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516106719190610ab2565b60405180910390a3600190509392505050565b60025f9054906101000a900460ff1681565b6004602052805f5260405f205f915090505481565b600180546106b890610be5565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490610be5565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b505050505081565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156107b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107af90610c5f565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108049190610d12565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108579190610d45565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516108bb9190610ab2565b60405180910390a36001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61095382610911565b61095d818561091b565b935061096d81856020860161092b565b61097681610939565b840191505092915050565b5f6020820190508181035f8301526109998184610949565b905092915050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6109ce826109a5565b9050919050565b6109de816109c4565b81146109e8575f5ffd5b50565b5f813590506109f9816109d5565b92915050565b5f819050919050565b610a11816109ff565b8114610a1b575f5ffd5b50565b5f81359050610a2c81610a08565b92915050565b5f5f60408385031215610a4857610a476109a1565b5b5f610a55858286016109eb565b9250506020610a6685828601610a1e565b9150509250929050565b5f8115159050919050565b610a8481610a70565b82525050565b5f602082019050610a9d5f830184610a7b565b92915050565b610aac816109ff565b82525050565b5f602082019050610ac55f830184610aa3565b92915050565b5f5f5f60608486031215610ae257610ae16109a1565b5b5f610aef868287016109eb565b9350506020610b00868287016109eb565b9250506040610b1186828701610a1e565b9150509250925092565b5f60ff82169050919050565b610b3081610b1b565b82525050565b5f602082019050610b495f830184610b27565b92915050565b5f60208284031215610b6457610b636109a1565b5b5f610b71848285016109eb565b91505092915050565b5f5f60408385031215610b9057610b8f6109a1565b5b5f610b9d858286016109eb565b9250506020610bae858286016109eb565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610bfc57607f821691505b602082108103610c0f57610c0e610bb8565b5b50919050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f610c4960148361091b565b9150610c5482610c15565b602082019050919050565b5f6020820190508181035f830152610c7681610c3d565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f610cb160168361091b565b9150610cbc82610c7d565b602082019050919050565b5f6020820190508181035f830152610cde81610ca5565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610d1c826109ff565b9150610d27836109ff565b9250828203905081811115610d3f57610d3e610ce5565b5b92915050565b5f610d4f826109ff565b9150610d5a836109ff565b9250828201905080821115610d7257610d71610ce5565b5b9291505056fea26469706673582212207182ee741671c2a140c5eb4e62cb72b950c446fa68846143d961b62f544f59c764736f6c634300081e0033 \ No newline at end of file diff --git a/scenarios/statebloat/contract-deploy/contract/StateBloatToken.go b/scenarios/statebloat/contract-deploy/contract/StateBloatToken.go new file mode 100644 index 00000000..bfb58592 --- /dev/null +++ b/scenarios/statebloat/contract-deploy/contract/StateBloatToken.go @@ -0,0 +1,791 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contract + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ContractMetaData contains all meta data concerning the Contract contract. +var ContractMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"salt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561000f575f5ffd5b50604051611503380380611503833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b608051610dae6107555f395f6108cf0152610dae5ff3fe608060405234801561000f575f5ffd5b506004361061009c575f3560e01c806370a082311161006457806370a082311461015a57806395d89b411461018a578063a9059cbb146101a8578063bfa0b133146101d8578063dd62ed3e146101f65761009c565b806306fdde03146100a0578063095ea7b3146100be57806318160ddd146100ee57806323b872dd1461010c578063313ce5671461013c575b5f5ffd5b6100a8610226565b6040516100b59190610981565b60405180910390f35b6100d860048036038101906100d39190610a32565b6102b1565b6040516100e59190610a8a565b60405180910390f35b6100f661039e565b6040516101039190610ab2565b60405180910390f35b61012660048036038101906101219190610acb565b6103a4565b6040516101339190610a8a565b60405180910390f35b610144610684565b6040516101519190610b36565b60405180910390f35b610174600480360381019061016f9190610b4f565b610696565b6040516101819190610ab2565b60405180910390f35b6101926106ab565b60405161019f9190610981565b60405180910390f35b6101c260048036038101906101bd9190610a32565b610737565b6040516101cf9190610a8a565b60405180910390f35b6101e06108cd565b6040516101ed9190610ab2565b60405180910390f35b610210600480360381019061020b9190610b7a565b6108f1565b60405161021d9190610ab2565b60405180910390f35b5f805461023290610be5565b80601f016020809104026020016040519081016040528092919081815260200182805461025e90610be5565b80156102a95780601f10610280576101008083540402835291602001916102a9565b820191905f5260205f20905b81548152906001019060200180831161028c57829003601f168201915b505050505081565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161038c9190610ab2565b60405180910390a36001905092915050565b60035481565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041c90610c5f565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156104e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d790610cc7565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461052c9190610d12565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461057f9190610d45565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461060d9190610d12565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516106719190610ab2565b60405180910390a3600190509392505050565b60025f9054906101000a900460ff1681565b6004602052805f5260405f205f915090505481565b600180546106b890610be5565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490610be5565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b505050505081565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156107b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107af90610c5f565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108049190610d12565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108579190610d45565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516108bb9190610ab2565b60405180910390a36001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61095382610911565b61095d818561091b565b935061096d81856020860161092b565b61097681610939565b840191505092915050565b5f6020820190508181035f8301526109998184610949565b905092915050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6109ce826109a5565b9050919050565b6109de816109c4565b81146109e8575f5ffd5b50565b5f813590506109f9816109d5565b92915050565b5f819050919050565b610a11816109ff565b8114610a1b575f5ffd5b50565b5f81359050610a2c81610a08565b92915050565b5f5f60408385031215610a4857610a476109a1565b5b5f610a55858286016109eb565b9250506020610a6685828601610a1e565b9150509250929050565b5f8115159050919050565b610a8481610a70565b82525050565b5f602082019050610a9d5f830184610a7b565b92915050565b610aac816109ff565b82525050565b5f602082019050610ac55f830184610aa3565b92915050565b5f5f5f60608486031215610ae257610ae16109a1565b5b5f610aef868287016109eb565b9350506020610b00868287016109eb565b9250506040610b1186828701610a1e565b9150509250925092565b5f60ff82169050919050565b610b3081610b1b565b82525050565b5f602082019050610b495f830184610b27565b92915050565b5f60208284031215610b6457610b636109a1565b5b5f610b71848285016109eb565b91505092915050565b5f5f60408385031215610b9057610b8f6109a1565b5b5f610b9d858286016109eb565b9250506020610bae858286016109eb565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610bfc57607f821691505b602082108103610c0f57610c0e610bb8565b5b50919050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f610c4960148361091b565b9150610c5482610c15565b602082019050919050565b5f6020820190508181035f830152610c7681610c3d565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f610cb160168361091b565b9150610cbc82610c7d565b602082019050919050565b5f6020820190508181035f830152610cde81610ca5565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610d1c826109ff565b9150610d27836109ff565b9250828203905081811115610d3f57610d3e610ce5565b5b92915050565b5f610d4f826109ff565b9150610d5a836109ff565b9250828201905080821115610d7257610d71610ce5565b5b9291505056fea26469706673582212207182ee741671c2a140c5eb4e62cb72b950c446fa68846143d961b62f544f59c764736f6c634300081e0033", +} + +// ContractABI is the input ABI used to generate the binding from. +// Deprecated: Use ContractMetaData.ABI instead. +var ContractABI = ContractMetaData.ABI + +// ContractBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ContractMetaData.Bin instead. +var ContractBin = ContractMetaData.Bin + +// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. +func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend, _salt *big.Int) (common.Address, *types.Transaction, *Contract, error) { + parsed, err := ContractMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend, _salt) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil +} + +// Contract is an auto generated Go binding around an Ethereum contract. +type Contract struct { + ContractCaller // Read-only binding to the contract + ContractTransactor // Write-only binding to the contract + ContractFilterer // Log filterer for contract events +} + +// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. +type ContractCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ContractTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ContractFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ContractSession struct { + Contract *Contract // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ContractCallerSession struct { + Contract *ContractCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ContractTransactorSession struct { + Contract *ContractTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. +type ContractRaw struct { + Contract *Contract // Generic contract binding to access the raw methods on +} + +// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ContractCallerRaw struct { + Contract *ContractCaller // Generic read-only contract binding to access the raw methods on +} + +// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ContractTransactorRaw struct { + Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewContract creates a new instance of Contract, bound to a specific deployed contract. +func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { + contract, err := bindContract(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil +} + +// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. +func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { + contract, err := bindContract(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ContractCaller{contract: contract}, nil +} + +// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. +func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { + contract, err := bindContract(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ContractTransactor{contract: contract}, nil +} + +// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. +func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { + contract, err := bindContract(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ContractFilterer{contract: contract}, nil +} + +// bindContract binds a generic wrapper to an already deployed contract. +func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ContractMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Contract.Contract.ContractTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Contract.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Contract.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Contract.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address , address ) view returns(uint256) +func (_Contract *ContractCaller) Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "allowance", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address , address ) view returns(uint256) +func (_Contract *ContractSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _Contract.Contract.Allowance(&_Contract.CallOpts, arg0, arg1) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address , address ) view returns(uint256) +func (_Contract *ContractCallerSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _Contract.Contract.Allowance(&_Contract.CallOpts, arg0, arg1) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address ) view returns(uint256) +func (_Contract *ContractCaller) BalanceOf(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "balanceOf", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address ) view returns(uint256) +func (_Contract *ContractSession) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _Contract.Contract.BalanceOf(&_Contract.CallOpts, arg0) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address ) view returns(uint256) +func (_Contract *ContractCallerSession) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _Contract.Contract.BalanceOf(&_Contract.CallOpts, arg0) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_Contract *ContractCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_Contract *ContractSession) Decimals() (uint8, error) { + return _Contract.Contract.Decimals(&_Contract.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_Contract *ContractCallerSession) Decimals() (uint8, error) { + return _Contract.Contract.Decimals(&_Contract.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_Contract *ContractCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_Contract *ContractSession) Name() (string, error) { + return _Contract.Contract.Name(&_Contract.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_Contract *ContractCallerSession) Name() (string, error) { + return _Contract.Contract.Name(&_Contract.CallOpts) +} + +// Salt is a free data retrieval call binding the contract method 0xbfa0b133. +// +// Solidity: function salt() view returns(uint256) +func (_Contract *ContractCaller) Salt(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "salt") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Salt is a free data retrieval call binding the contract method 0xbfa0b133. +// +// Solidity: function salt() view returns(uint256) +func (_Contract *ContractSession) Salt() (*big.Int, error) { + return _Contract.Contract.Salt(&_Contract.CallOpts) +} + +// Salt is a free data retrieval call binding the contract method 0xbfa0b133. +// +// Solidity: function salt() view returns(uint256) +func (_Contract *ContractCallerSession) Salt() (*big.Int, error) { + return _Contract.Contract.Salt(&_Contract.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Contract *ContractCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Contract *ContractSession) Symbol() (string, error) { + return _Contract.Contract.Symbol(&_Contract.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Contract *ContractCallerSession) Symbol() (string, error) { + return _Contract.Contract.Symbol(&_Contract.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_Contract *ContractCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_Contract *ContractSession) TotalSupply() (*big.Int, error) { + return _Contract.Contract.TotalSupply(&_Contract.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_Contract *ContractCallerSession) TotalSupply() (*big.Int, error) { + return _Contract.Contract.TotalSupply(&_Contract.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_Contract *ContractTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_Contract *ContractSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.Approve(&_Contract.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.Approve(&_Contract.TransactOpts, spender, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_Contract *ContractSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.Transfer(&_Contract.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.Transfer(&_Contract.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom(&_Contract.TransactOpts, from, to, value) +} + +// ContractApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the Contract contract. +type ContractApprovalIterator struct { + Event *ContractApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractApproval represents a Approval event raised by the Contract contract. +type ContractApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_Contract *ContractFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ContractApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Contract.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &ContractApprovalIterator{contract: _Contract.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_Contract *ContractFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ContractApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Contract.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractApproval) + if err := _Contract.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_Contract *ContractFilterer) ParseApproval(log types.Log) (*ContractApproval, error) { + event := new(ContractApproval) + if err := _Contract.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the Contract contract. +type ContractTransferIterator struct { + Event *ContractTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractTransfer represents a Transfer event raised by the Contract contract. +type ContractTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_Contract *ContractFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ContractTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Contract.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &ContractTransferIterator{contract: _Contract.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_Contract *ContractFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ContractTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Contract.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractTransfer) + if err := _Contract.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_Contract *ContractFilterer) ParseTransfer(log types.Log) (*ContractTransfer, error) { + event := new(ContractTransfer) + if err := _Contract.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/scenarios/statebloat/contract-deploy/contract/StateBloatToken.sol b/scenarios/statebloat/contract-deploy/contract/StateBloatToken.sol new file mode 100644 index 00000000..28dc8454 --- /dev/null +++ b/scenarios/statebloat/contract-deploy/contract/StateBloatToken.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.22; + +contract StateBloatToken { + string public name; + string public symbol; + uint8 public decimals; + uint256 public totalSupply; + mapping(address => uint256) public balanceOf; + mapping(address => mapping(address => uint256)) public allowance; + + // Salt to make each deployment unique + uint256 public immutable salt; + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); + + constructor(uint256 _salt) { + name = "State Bloat Token"; + symbol = "SBT"; + decimals = 18; + salt = _salt; + + // Initialize with some state + totalSupply = 1000000 * 10 ** decimals; + balanceOf[msg.sender] = totalSupply; + emit Transfer(address(0), msg.sender, totalSupply); + } + + function transfer(address to, uint256 value) public returns (bool) { + require(balanceOf[msg.sender] >= value, "Insufficient balance"); + balanceOf[msg.sender] -= value; + balanceOf[to] += value; + emit Transfer(msg.sender, to, value); + return true; + } + + function approve(address spender, uint256 value) public returns (bool) { + allowance[msg.sender][spender] = value; + emit Approval(msg.sender, spender, value); + return true; + } + + function transferFrom( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } +} diff --git a/scenarios/statebloat/contract-deploy/contract_deploy.go b/scenarios/statebloat/contract-deploy/contract_deploy.go new file mode 100644 index 00000000..650d7cab --- /dev/null +++ b/scenarios/statebloat/contract-deploy/contract_deploy.go @@ -0,0 +1,305 @@ +package contractdeploy + +import ( + "context" + "crypto/rand" + "fmt" + "math/big" + "sync" + "sync/atomic" + "time" + + "golang.org/x/time/rate" + "gopkg.in/yaml.v3" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/types" + "github.com/sirupsen/logrus" + "github.com/spf13/pflag" + + "github.com/ethpandaops/spamoor/scenarios/statebloat/contract-deploy/contract" + "github.com/ethpandaops/spamoor/scenariotypes" + "github.com/ethpandaops/spamoor/spamoor" + "github.com/ethpandaops/spamoor/txbuilder" + "github.com/ethpandaops/spamoor/utils" +) + +type ScenarioOptions struct { + TotalCount uint64 `yaml:"total_count"` + Throughput uint64 `yaml:"throughput"` + MaxPending uint64 `yaml:"max_pending"` + MaxWallets uint64 `yaml:"max_wallets"` + Rebroadcast uint64 `yaml:"rebroadcast"` + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` + GasPerBlock uint64 `yaml:"gas_per_block"` + ClientGroup string `yaml:"client_group"` +} + +type Scenario struct { + options ScenarioOptions + logger *logrus.Entry + walletPool *spamoor.WalletPool + + pendingChan chan bool + pendingWGroup sync.WaitGroup +} + +var ScenarioName = "contract-deploy" +var ScenarioDefaultOptions = ScenarioOptions{ + TotalCount: 0, + Throughput: 0, + MaxPending: 0, + MaxWallets: 0, + Rebroadcast: 30, + BaseFee: 20, + TipFee: 2, + GasPerBlock: 0, + ClientGroup: "", +} +var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ + Name: ScenarioName, + Description: "Deploy contracts to create state bloat", + DefaultOptions: ScenarioDefaultOptions, + NewScenario: newScenario, +} + +func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { + return &Scenario{ + logger: logger.WithField("scenario", ScenarioName), + } +} + +func (s *Scenario) Flags(flags *pflag.FlagSet) error { + flags.Uint64VarP(&s.options.TotalCount, "count", "c", ScenarioDefaultOptions.TotalCount, "Total number of contracts to deploy") + flags.Uint64VarP(&s.options.Throughput, "throughput", "t", ScenarioDefaultOptions.Throughput, "Number of contracts to deploy per slot") + flags.Uint64Var(&s.options.MaxPending, "max-pending", ScenarioDefaultOptions.MaxPending, "Maximum number of pending transactions") + flags.Uint64Var(&s.options.MaxWallets, "max-wallets", ScenarioDefaultOptions.MaxWallets, "Maximum number of child wallets to use") + flags.Uint64Var(&s.options.Rebroadcast, "rebroadcast", ScenarioDefaultOptions.Rebroadcast, "Number of seconds to wait before re-broadcasting a transaction") + flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Max fee per gas to use in transactions (in gwei)") + flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") + flags.Uint64Var(&s.options.GasPerBlock, "gas-per-block", ScenarioDefaultOptions.GasPerBlock, "Target gas to use per block (will calculate number of contracts to deploy)") + flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") + return nil +} + +func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { + s.walletPool = walletPool + + if config != "" { + err := yaml.Unmarshal([]byte(config), &s.options) + if err != nil { + return fmt.Errorf("failed to unmarshal config: %w", err) + } + } + + if s.options.MaxWallets > 0 { + walletPool.SetWalletCount(s.options.MaxWallets) + } else if s.options.TotalCount > 0 { + if s.options.TotalCount < 1000 { + walletPool.SetWalletCount(s.options.TotalCount) + } else { + walletPool.SetWalletCount(1000) + } + } else { + if s.options.Throughput*10 < 1000 { + walletPool.SetWalletCount(s.options.Throughput * 10) + } else { + walletPool.SetWalletCount(1000) + } + } + + if s.options.TotalCount == 0 && s.options.Throughput == 0 && s.options.GasPerBlock == 0 { + return fmt.Errorf("neither total count, throughput, nor gas per block limit set, must define at least one of them (see --help for list of all flags)") + } + + if s.options.MaxPending > 0 { + s.pendingChan = make(chan bool, s.options.MaxPending) + } + + return nil +} + +func (s *Scenario) Config() string { + yamlBytes, _ := yaml.Marshal(&s.options) + return string(yamlBytes) +} + +func (s *Scenario) Run(ctx context.Context) error { + txIdxCounter := uint64(0) + pendingCount := atomic.Int64{} + txCount := atomic.Uint64{} + var lastChan chan bool + + s.logger.Infof("starting scenario: %s", ScenarioName) + defer s.logger.Infof("scenario %s finished.", ScenarioName) + + // Calculate throughput based on gas per block if specified + throughput := s.options.Throughput + if s.options.GasPerBlock > 0 { + // Each deployment costs ~4.967M gas + throughput = s.options.GasPerBlock / 4967200 + if throughput == 0 { + throughput = 1 + } + s.logger.Infof("calculated throughput: %d contracts per block (target gas: %d)", throughput, s.options.GasPerBlock) + } + + initialRate := rate.Limit(float64(throughput) / float64(utils.SecondsPerSlot)) + if initialRate == 0 { + initialRate = rate.Inf + } + limiter := rate.NewLimiter(initialRate, 1) + + for { + if err := limiter.Wait(ctx); err != nil { + if ctx.Err() != nil { + break + } + + s.logger.Debugf("rate limited: %s", err.Error()) + time.Sleep(100 * time.Millisecond) + continue + } + + txIdx := txIdxCounter + txIdxCounter++ + + if s.pendingChan != nil { + // await pending transactions + s.pendingChan <- true + } + pendingCount.Add(1) + currentChan := make(chan bool, 1) + + go func(txIdx uint64, lastChan, currentChan chan bool) { + defer func() { + pendingCount.Add(-1) + currentChan <- true + }() + + logger := s.logger + tx, client, wallet, err := s.sendTx(ctx, txIdx, func() { + if s.pendingChan != nil { + time.Sleep(100 * time.Millisecond) + <-s.pendingChan + } + }) + if client != nil { + logger = logger.WithField("rpc", client.GetName()) + } + if tx != nil { + logger = logger.WithField("nonce", tx.Nonce()) + } + if wallet != nil { + logger = logger.WithField("wallet", s.walletPool.GetWalletName(wallet.GetAddress())) + } + if lastChan != nil { + <-lastChan + close(lastChan) + } + if err != nil { + logger.Warnf("could not send transaction: %v", err) + return + } + + txCount.Add(1) + if lastChan != nil { + <-lastChan + close(lastChan) + } + logger.Infof("sent tx #%6d: %v", txIdx+1, tx.Hash().String()) + }(txIdx, lastChan, currentChan) + + lastChan = currentChan + + count := txCount.Load() + uint64(pendingCount.Load()) + if s.options.TotalCount > 0 && count >= s.options.TotalCount { + break + } + } + s.pendingWGroup.Wait() + s.logger.Infof("finished sending transactions, awaiting block inclusion...") + + return nil +} + +func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) (*types.Transaction, *txbuilder.Client, *txbuilder.Wallet, error) { + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, int(txIdx), s.options.ClientGroup) + wallet := s.walletPool.GetWallet(spamoor.SelectWalletByIndex, int(txIdx)) + + if client == nil { + return nil, nil, nil, fmt.Errorf("no client available") + } + + var feeCap *big.Int + var tipCap *big.Int + + if s.options.BaseFee > 0 { + feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) + } + if s.options.TipFee > 0 { + tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) + } + + // Generate random salt for unique contract + salt := make([]byte, 32) + _, err := rand.Read(salt) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to generate salt: %w", err) + } + saltInt := new(big.Int).SetBytes(salt) + + // Get chain ID + chainId, err := client.GetChainId(ctx) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to get chain ID: %w", err) + } + + // Deploy contract + auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), chainId) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to create auth: %w", err) + } + + auth.Nonce = big.NewInt(int64(wallet.GetNonce())) + auth.Value = big.NewInt(0) + auth.GasLimit = 5000000 // Enough for 24kB contract + auth.GasPrice = feeCap + auth.GasTipCap = tipCap + + // Get contract bytecode + bytecode, err := contract.StateBloatTokenMetaData.GetDeployedBytecode("StateBloatToken") + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to get bytecode: %w", err) + } + + // Pack constructor arguments + packedArgs, err := contract.StateBloatTokenMetaData.Abi.Pack("", saltInt) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to pack constructor args: %w", err) + } + + // Combine bytecode and constructor args + fullBytecode := append(bytecode, packedArgs...) + + // Create transaction + tx := types.NewContractCreation(auth.Nonce.Uint64(), auth.Value, auth.GasLimit, auth.GasPrice, fullBytecode) + + // Sign transaction + signedTx, err := auth.Signer(auth.From, tx) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to sign transaction: %w", err) + } + + // Send transaction + err = client.SendTransactionCtx(ctx, signedTx) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to send transaction: %w", err) + } + + // Update nonce + wallet.SetNonce(wallet.GetNonce() + 1) + + return signedTx, client, wallet, nil +} From 372feec634ffa983a11562cb672ef844c520ff28 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 7 May 2025 17:13:24 +0200 Subject: [PATCH 03/39] refactor(contract-deploy): simplify deployment rate control - Remove redundant throughput flag and consolidate to contracts-per-tx - Remove count flag and related code for cleaner interface - Update wallet count calculation to use contracts-per-tx - Keep only two deployment rate control methods: - contracts-per-tx: direct control of contracts per transaction - gas-per-block: calculate contracts based on target gas The scenario now runs indefinitely until stopped, with cleaner and more focused configuration options. --- .../contract-deploy/contract_deploy.go | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/scenarios/statebloat/contract-deploy/contract_deploy.go b/scenarios/statebloat/contract-deploy/contract_deploy.go index 650d7cab..12363833 100644 --- a/scenarios/statebloat/contract-deploy/contract_deploy.go +++ b/scenarios/statebloat/contract-deploy/contract_deploy.go @@ -25,15 +25,14 @@ import ( ) type ScenarioOptions struct { - TotalCount uint64 `yaml:"total_count"` - Throughput uint64 `yaml:"throughput"` - MaxPending uint64 `yaml:"max_pending"` - MaxWallets uint64 `yaml:"max_wallets"` - Rebroadcast uint64 `yaml:"rebroadcast"` - BaseFee uint64 `yaml:"base_fee"` - TipFee uint64 `yaml:"tip_fee"` - GasPerBlock uint64 `yaml:"gas_per_block"` - ClientGroup string `yaml:"client_group"` + MaxPending uint64 `yaml:"max_pending"` + MaxWallets uint64 `yaml:"max_wallets"` + Rebroadcast uint64 `yaml:"rebroadcast"` + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` + GasPerBlock uint64 `yaml:"gas_per_block"` + ClientGroup string `yaml:"client_group"` + ContractsPerTx uint64 `yaml:"contracts_per_tx"` } type Scenario struct { @@ -47,15 +46,14 @@ type Scenario struct { var ScenarioName = "contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ - TotalCount: 0, - Throughput: 0, - MaxPending: 0, - MaxWallets: 0, - Rebroadcast: 30, - BaseFee: 20, - TipFee: 2, - GasPerBlock: 0, - ClientGroup: "", + MaxPending: 0, + MaxWallets: 0, + Rebroadcast: 30, + BaseFee: 20, + TipFee: 2, + GasPerBlock: 0, + ClientGroup: "default", + ContractsPerTx: 1, } var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ Name: ScenarioName, @@ -71,8 +69,6 @@ func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { } func (s *Scenario) Flags(flags *pflag.FlagSet) error { - flags.Uint64VarP(&s.options.TotalCount, "count", "c", ScenarioDefaultOptions.TotalCount, "Total number of contracts to deploy") - flags.Uint64VarP(&s.options.Throughput, "throughput", "t", ScenarioDefaultOptions.Throughput, "Number of contracts to deploy per slot") flags.Uint64Var(&s.options.MaxPending, "max-pending", ScenarioDefaultOptions.MaxPending, "Maximum number of pending transactions") flags.Uint64Var(&s.options.MaxWallets, "max-wallets", ScenarioDefaultOptions.MaxWallets, "Maximum number of child wallets to use") flags.Uint64Var(&s.options.Rebroadcast, "rebroadcast", ScenarioDefaultOptions.Rebroadcast, "Number of seconds to wait before re-broadcasting a transaction") @@ -80,6 +76,7 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") flags.Uint64Var(&s.options.GasPerBlock, "gas-per-block", ScenarioDefaultOptions.GasPerBlock, "Target gas to use per block (will calculate number of contracts to deploy)") flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") + flags.Uint64Var(&s.options.ContractsPerTx, "contracts-per-tx", ScenarioDefaultOptions.ContractsPerTx, "Number of contracts to deploy in a single transaction") return nil } @@ -95,22 +92,18 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { if s.options.MaxWallets > 0 { walletPool.SetWalletCount(s.options.MaxWallets) - } else if s.options.TotalCount > 0 { - if s.options.TotalCount < 1000 { - walletPool.SetWalletCount(s.options.TotalCount) - } else { - walletPool.SetWalletCount(1000) - } } else { - if s.options.Throughput*10 < 1000 { - walletPool.SetWalletCount(s.options.Throughput * 10) + if s.options.ContractsPerTx*10 < 1000 { + walletPool.SetWalletCount(s.options.ContractsPerTx * 10) } else { walletPool.SetWalletCount(1000) } } - if s.options.TotalCount == 0 && s.options.Throughput == 0 && s.options.GasPerBlock == 0 { - return fmt.Errorf("neither total count, throughput, nor gas per block limit set, must define at least one of them (see --help for list of all flags)") + // TODO: We need to check that we don't exceed block gas limit with the number of contracts we're deploying. + // Otherwise fail with an error message that explains that we're exceeding the block gas limit. + if s.options.GasPerBlock == 0 && s.options.ContractsPerTx == 0 { + return fmt.Errorf("neither gas per block limit nor contracts per tx set, must define at least one of them (see --help for list of all flags)") } if s.options.MaxPending > 0 { @@ -134,8 +127,8 @@ func (s *Scenario) Run(ctx context.Context) error { s.logger.Infof("starting scenario: %s", ScenarioName) defer s.logger.Infof("scenario %s finished.", ScenarioName) - // Calculate throughput based on gas per block if specified - throughput := s.options.Throughput + // Calculate throughput based on gas per block or contracts per tx + throughput := s.options.ContractsPerTx if s.options.GasPerBlock > 0 { // Each deployment costs ~4.967M gas throughput = s.options.GasPerBlock / 4967200 @@ -143,6 +136,12 @@ func (s *Scenario) Run(ctx context.Context) error { throughput = 1 } s.logger.Infof("calculated throughput: %d contracts per block (target gas: %d)", throughput, s.options.GasPerBlock) + } else { + // Calculate gas needed for the specified number of contracts + // TODO: This should be a constant value, not a variable. We should change it everywhere. + gasPerContract := uint64(4967200) // ~4.967M gas per contract + totalGas := gasPerContract * s.options.ContractsPerTx + s.logger.Infof("calculated gas: %d per tx for %d contracts", totalGas, throughput) } initialRate := rate.Limit(float64(throughput) / float64(utils.SecondsPerSlot)) @@ -212,11 +211,6 @@ func (s *Scenario) Run(ctx context.Context) error { }(txIdx, lastChan, currentChan) lastChan = currentChan - - count := txCount.Load() + uint64(pendingCount.Load()) - if s.options.TotalCount > 0 && count >= s.options.TotalCount { - break - } } s.pendingWGroup.Wait() s.logger.Infof("finished sending transactions, awaiting block inclusion...") From b9ac6eb8b655cba76c306a3723edb2e0a7135071 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 7 May 2025 17:24:01 +0200 Subject: [PATCH 04/39] fix: use correct contract metadata fields for bytecode and ABI packing --- .../{contract-deploy => contract_deploy}/README.md | 0 .../contract/README.md | 0 .../contract/StateBloatToken.abi | 0 .../contract/StateBloatToken.bin | 0 .../contract/StateBloatToken.go | 0 .../contract/StateBloatToken.sol | 0 .../contract_deploy.go | 12 ++++++++---- 7 files changed, 8 insertions(+), 4 deletions(-) rename scenarios/statebloat/{contract-deploy => contract_deploy}/README.md (100%) rename scenarios/statebloat/{contract-deploy => contract_deploy}/contract/README.md (100%) rename scenarios/statebloat/{contract-deploy => contract_deploy}/contract/StateBloatToken.abi (100%) rename scenarios/statebloat/{contract-deploy => contract_deploy}/contract/StateBloatToken.bin (100%) rename scenarios/statebloat/{contract-deploy => contract_deploy}/contract/StateBloatToken.go (100%) rename scenarios/statebloat/{contract-deploy => contract_deploy}/contract/StateBloatToken.sol (100%) rename scenarios/statebloat/{contract-deploy => contract_deploy}/contract_deploy.go (96%) diff --git a/scenarios/statebloat/contract-deploy/README.md b/scenarios/statebloat/contract_deploy/README.md similarity index 100% rename from scenarios/statebloat/contract-deploy/README.md rename to scenarios/statebloat/contract_deploy/README.md diff --git a/scenarios/statebloat/contract-deploy/contract/README.md b/scenarios/statebloat/contract_deploy/contract/README.md similarity index 100% rename from scenarios/statebloat/contract-deploy/contract/README.md rename to scenarios/statebloat/contract_deploy/contract/README.md diff --git a/scenarios/statebloat/contract-deploy/contract/StateBloatToken.abi b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi similarity index 100% rename from scenarios/statebloat/contract-deploy/contract/StateBloatToken.abi rename to scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi diff --git a/scenarios/statebloat/contract-deploy/contract/StateBloatToken.bin b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin similarity index 100% rename from scenarios/statebloat/contract-deploy/contract/StateBloatToken.bin rename to scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin diff --git a/scenarios/statebloat/contract-deploy/contract/StateBloatToken.go b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go similarity index 100% rename from scenarios/statebloat/contract-deploy/contract/StateBloatToken.go rename to scenarios/statebloat/contract_deploy/contract/StateBloatToken.go diff --git a/scenarios/statebloat/contract-deploy/contract/StateBloatToken.sol b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol similarity index 100% rename from scenarios/statebloat/contract-deploy/contract/StateBloatToken.sol rename to scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol diff --git a/scenarios/statebloat/contract-deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go similarity index 96% rename from scenarios/statebloat/contract-deploy/contract_deploy.go rename to scenarios/statebloat/contract_deploy/contract_deploy.go index 12363833..7df17c47 100644 --- a/scenarios/statebloat/contract-deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -17,7 +17,8 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/pflag" - "github.com/ethpandaops/spamoor/scenarios/statebloat/contract-deploy/contract" + "github.com/ethereum/go-ethereum/common" + "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy/contract" "github.com/ethpandaops/spamoor/scenariotypes" "github.com/ethpandaops/spamoor/spamoor" "github.com/ethpandaops/spamoor/txbuilder" @@ -263,13 +264,16 @@ func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) auth.GasTipCap = tipCap // Get contract bytecode - bytecode, err := contract.StateBloatTokenMetaData.GetDeployedBytecode("StateBloatToken") + bytecode := common.FromHex(contract.ContractBin) + + // Get ABI + parsed, err := contract.ContractMetaData.GetAbi() if err != nil { - return nil, nil, nil, fmt.Errorf("failed to get bytecode: %w", err) + return nil, nil, nil, fmt.Errorf("failed to get ABI: %w", err) } // Pack constructor arguments - packedArgs, err := contract.StateBloatTokenMetaData.Abi.Pack("", saltInt) + packedArgs, err := parsed.Pack("", saltInt) if err != nil { return nil, nil, nil, fmt.Errorf("failed to pack constructor args: %w", err) } From 76840e666da2d0c346cd5a788791416b4fca93ef Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 7 May 2025 17:54:45 +0200 Subject: [PATCH 05/39] chore: rename gas constant to uppercase for better visibility --- .../statebloat/contract_deploy/contract_deploy.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 7df17c47..0f95b40b 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -25,6 +25,11 @@ import ( "github.com/ethpandaops/spamoor/utils" ) +const ( + // GAS_PER_CONTRACT is the estimated gas cost for deploying one StateBloatToken contract + GAS_PER_CONTRACT = 4970000 // ~4.97M gas per contract +) + type ScenarioOptions struct { MaxPending uint64 `yaml:"max_pending"` MaxWallets uint64 `yaml:"max_wallets"` @@ -131,17 +136,15 @@ func (s *Scenario) Run(ctx context.Context) error { // Calculate throughput based on gas per block or contracts per tx throughput := s.options.ContractsPerTx if s.options.GasPerBlock > 0 { - // Each deployment costs ~4.967M gas - throughput = s.options.GasPerBlock / 4967200 + // Each deployment costs ~4.97M gas + throughput = s.options.GasPerBlock / GAS_PER_CONTRACT if throughput == 0 { throughput = 1 } s.logger.Infof("calculated throughput: %d contracts per block (target gas: %d)", throughput, s.options.GasPerBlock) } else { // Calculate gas needed for the specified number of contracts - // TODO: This should be a constant value, not a variable. We should change it everywhere. - gasPerContract := uint64(4967200) // ~4.967M gas per contract - totalGas := gasPerContract * s.options.ContractsPerTx + totalGas := GAS_PER_CONTRACT * s.options.ContractsPerTx s.logger.Infof("calculated gas: %d per tx for %d contracts", totalGas, throughput) } From dbf118de9f037dda6c54cfedd456779a07701c03 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 7 May 2025 18:20:32 +0200 Subject: [PATCH 06/39] feat(contract-deploy): add block gas limit validation - Add validation to ensure contract deployments don't exceed block gas limit - Check both gas-per-block and contracts-per-tx against block gas limit - Add clear error messages when gas limits are exceeded - Move validation to Run() function to access context --- .../contract_deploy/contract_deploy.go | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 0f95b40b..10acc361 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -96,6 +96,10 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { } } + if s.options.GasPerBlock == 0 && s.options.ContractsPerTx == 0 { + return fmt.Errorf("neither gas per block limit nor contracts per tx set, must define at least one of them (see --help for list of all flags)") + } + if s.options.MaxWallets > 0 { walletPool.SetWalletCount(s.options.MaxWallets) } else { @@ -106,12 +110,6 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { } } - // TODO: We need to check that we don't exceed block gas limit with the number of contracts we're deploying. - // Otherwise fail with an error message that explains that we're exceeding the block gas limit. - if s.options.GasPerBlock == 0 && s.options.ContractsPerTx == 0 { - return fmt.Errorf("neither gas per block limit nor contracts per tx set, must define at least one of them (see --help for list of all flags)") - } - if s.options.MaxPending > 0 { s.pendingChan = make(chan bool, s.options.MaxPending) } @@ -133,6 +131,26 @@ func (s *Scenario) Run(ctx context.Context) error { s.logger.Infof("starting scenario: %s", ScenarioName) defer s.logger.Infof("scenario %s finished.", ScenarioName) + // Get block gas limit and validate contract deployment gas + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) + if client == nil { + return fmt.Errorf("no client available") + } + block, err := client.GetEthClient().BlockByNumber(ctx, nil) + if err != nil { + return fmt.Errorf("failed to get latest block: %w", err) + } + blockGasLimit := block.GasLimit() + + // Validate gas usage against block limit + if s.options.GasPerBlock > blockGasLimit { + return fmt.Errorf("gas per block (%d) exceeds block gas limit (%d)", s.options.GasPerBlock, blockGasLimit) + } + if s.options.ContractsPerTx*GAS_PER_CONTRACT > blockGasLimit { + return fmt.Errorf("contracts per tx (%d) requires %d gas, exceeding block gas limit (%d)", + s.options.ContractsPerTx, s.options.ContractsPerTx*GAS_PER_CONTRACT, blockGasLimit) + } + // Calculate throughput based on gas per block or contracts per tx throughput := s.options.ContractsPerTx if s.options.GasPerBlock > 0 { From 5438bdd2f203182fb64cbc4579ab88539e8a35fd Mon Sep 17 00:00:00 2001 From: CPerezz Date: Thu, 8 May 2025 15:45:41 +0200 Subject: [PATCH 07/39] add: Basic testing for contract deploying --- go.mod | 3 + .../contract_deploy/contract_deploy.go | 5 - .../contract_deploy/contract_deploy_test.go | 114 ++++++++++++++++++ 3 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 scenarios/statebloat/contract_deploy/contract_deploy_test.go diff --git a/go.mod b/go.mod index 71054d9b..ebdfcc40 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/pressly/goose/v3 v3.24.2 github.com/sirupsen/logrus v1.9.3 github.com/spf13/pflag v1.0.6 + github.com/stretchr/testify v1.10.0 github.com/swaggo/http-swagger v1.3.4 github.com/swaggo/swag v1.16.4 github.com/tdewolff/minify v2.3.6+incompatible @@ -30,6 +31,7 @@ require ( github.com/consensys/bavard v0.1.27 // indirect github.com/consensys/gnark-crypto v0.16.0 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -49,6 +51,7 @@ require ( github.com/mfridman/interpolate v0.0.2 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/sethvargo/go-retry v0.3.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 10acc361..cf3a293b 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -217,7 +217,6 @@ func (s *Scenario) Run(ctx context.Context) error { } if lastChan != nil { <-lastChan - close(lastChan) } if err != nil { logger.Warnf("could not send transaction: %v", err) @@ -225,10 +224,6 @@ func (s *Scenario) Run(ctx context.Context) error { } txCount.Add(1) - if lastChan != nil { - <-lastChan - close(lastChan) - } logger.Infof("sent tx #%6d: %v", txIdx+1, tx.Hash().String()) }(txIdx, lastChan, currentChan) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy_test.go b/scenarios/statebloat/contract_deploy/contract_deploy_test.go new file mode 100644 index 00000000..77b8be28 --- /dev/null +++ b/scenarios/statebloat/contract_deploy/contract_deploy_test.go @@ -0,0 +1,114 @@ +package contractdeploy + +import ( + "context" + "os/exec" + "testing" + "time" + + "github.com/ethereum/go-ethereum/ethclient" + "github.com/holiman/uint256" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/ethpandaops/spamoor/spamoor" + "github.com/ethpandaops/spamoor/txbuilder" + "github.com/ethpandaops/spamoor/utils" +) + +func TestContractDeploy(t *testing.T) { + // Start Anvil server with legacy transactions + cmd := exec.Command("anvil", "--hardfork", "pectra") + err := cmd.Start() + require.NoError(t, err) + defer cmd.Process.Kill() + + // Wait for Anvil to start + time.Sleep(2 * time.Second) + + // Connect to Anvil + client, err := ethclient.Dial("http://localhost:8545") + require.NoError(t, err) + defer client.Close() + + // Create context + ctx := context.Background() + logger := logrus.New().WithField("test", "contract-deploy") + + // Create client pool + clientPool := spamoor.NewClientPool(ctx, []string{"http://localhost:8545"}, logger) + err = clientPool.PrepareClients() + require.NoError(t, err) + + // Create root wallet using a pre-funded Anvil account + rootWallet, err := spamoor.InitRootWallet(ctx, "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", clientPool.GetClient(spamoor.SelectClientByIndex, 0, ""), logger) + require.NoError(t, err) + + // Create tx pool + txpool := txbuilder.NewTxPool(&txbuilder.TxPoolOptions{ + Context: ctx, + GetClientFn: func(index int, random bool) *txbuilder.Client { + mode := spamoor.SelectClientByIndex + if random { + mode = spamoor.SelectClientRandom + } + return clientPool.GetClient(mode, index, "") + }, + GetClientCountFn: func() int { + return len(clientPool.GetAllClients()) + }, + }) + + // Create wallet pool + walletPool := spamoor.NewWalletPool(ctx, logger, rootWallet, clientPool, txpool) + walletPool.SetWalletCount(1) + walletPool.SetRefillAmount(utils.EtherToWei(uint256.NewInt(1))) // 1 ETH + walletPool.SetRefillBalance(utils.EtherToWei(uint256.NewInt(1))) // 1 ETH + walletPool.SetRefillInterval(60) + + // Create scenario instance + scenario := newScenario(logger) + + // Configure scenario with 6 contracts per tx which is the maximum allowed by the latest fork. + config := ` +max_pending: 0 +max_wallets: 1 +rebroadcast: 30 +base_fee: 20 +tip_fee: 2 +gas_per_block: 30000000 +client_group: default +contracts_per_tx: 6 +` + err = scenario.Init(walletPool, config) + require.NoError(t, err) + + // Prepare wallets + err = walletPool.PrepareWallets(true) + require.NoError(t, err) + + // Create context with timeout + runCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + + // Run scenario + err = scenario.Run(runCtx) + require.NoError(t, err) + + // Verify contract deployment + block, err := client.BlockByNumber(ctx, nil) + require.NoError(t, err) + assert.Greater(t, block.Transactions().Len(), 0) + + // Get transaction receipt + tx := block.Transactions()[0] + receipt, err := client.TransactionReceipt(ctx, tx.Hash()) + require.NoError(t, err) + assert.Equal(t, uint64(1), receipt.Status) + + // Verify contract was created + code, err := client.CodeAt(ctx, receipt.ContractAddress, nil) + require.NoError(t, err) + assert.Greater(t, len(code), 0) +} From af640f2086574c8665b71d6dd76cbd82b5f2f094 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 12 May 2025 12:17:42 +0200 Subject: [PATCH 08/39] feat(contract-deploy): enhance contract deployment scenarios - Introduce multiple test cases for contract deployment: using contracts per block, gas per block, and handling invalid configurations. - Update config opts to replace `contracts-per-tx` with `contracts-per-block` for better clarity. - Add error handling for scenarios where neither gas per block nor contracts per block is set. --- .../contract_deploy/contract_deploy.go | 96 +++++-------- .../contract_deploy/contract_deploy_test.go | 126 +++++++++++++----- 2 files changed, 128 insertions(+), 94 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index cf3a293b..a49e3628 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -17,7 +17,6 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/pflag" - "github.com/ethereum/go-ethereum/common" "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy/contract" "github.com/ethpandaops/spamoor/scenariotypes" "github.com/ethpandaops/spamoor/spamoor" @@ -31,14 +30,14 @@ const ( ) type ScenarioOptions struct { - MaxPending uint64 `yaml:"max_pending"` - MaxWallets uint64 `yaml:"max_wallets"` - Rebroadcast uint64 `yaml:"rebroadcast"` - BaseFee uint64 `yaml:"base_fee"` - TipFee uint64 `yaml:"tip_fee"` - GasPerBlock uint64 `yaml:"gas_per_block"` - ClientGroup string `yaml:"client_group"` - ContractsPerTx uint64 `yaml:"contracts_per_tx"` + MaxPending uint64 `yaml:"max_pending"` + MaxWallets uint64 `yaml:"max_wallets"` + Rebroadcast uint64 `yaml:"rebroadcast"` + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` + GasPerBlock uint64 `yaml:"gas_per_block"` + ClientGroup string `yaml:"client_group"` + ContractsPerBlock uint64 `yaml:"contracts_per_block"` } type Scenario struct { @@ -52,14 +51,14 @@ type Scenario struct { var ScenarioName = "contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ - MaxPending: 0, - MaxWallets: 0, - Rebroadcast: 30, - BaseFee: 20, - TipFee: 2, - GasPerBlock: 0, - ClientGroup: "default", - ContractsPerTx: 1, + MaxPending: 0, + MaxWallets: 0, + Rebroadcast: 30, + BaseFee: 20, + TipFee: 2, + GasPerBlock: 0, + ClientGroup: "default", + ContractsPerBlock: 1, } var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ Name: ScenarioName, @@ -82,7 +81,7 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") flags.Uint64Var(&s.options.GasPerBlock, "gas-per-block", ScenarioDefaultOptions.GasPerBlock, "Target gas to use per block (will calculate number of contracts to deploy)") flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") - flags.Uint64Var(&s.options.ContractsPerTx, "contracts-per-tx", ScenarioDefaultOptions.ContractsPerTx, "Number of contracts to deploy in a single transaction") + flags.Uint64Var(&s.options.ContractsPerBlock, "contracts-per-block", ScenarioDefaultOptions.ContractsPerBlock, "Number of contracts to deploy per block") return nil } @@ -96,15 +95,15 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { } } - if s.options.GasPerBlock == 0 && s.options.ContractsPerTx == 0 { - return fmt.Errorf("neither gas per block limit nor contracts per tx set, must define at least one of them (see --help for list of all flags)") + if s.options.GasPerBlock == 0 && s.options.ContractsPerBlock == 0 { + return fmt.Errorf("neither gas per block limit nor contracts per block set, must define at least one of them (see --help for list of all flags)") } if s.options.MaxWallets > 0 { walletPool.SetWalletCount(s.options.MaxWallets) } else { - if s.options.ContractsPerTx*10 < 1000 { - walletPool.SetWalletCount(s.options.ContractsPerTx * 10) + if s.options.ContractsPerBlock*10 < 1000 { + walletPool.SetWalletCount(s.options.ContractsPerBlock * 10) } else { walletPool.SetWalletCount(1000) } @@ -146,13 +145,13 @@ func (s *Scenario) Run(ctx context.Context) error { if s.options.GasPerBlock > blockGasLimit { return fmt.Errorf("gas per block (%d) exceeds block gas limit (%d)", s.options.GasPerBlock, blockGasLimit) } - if s.options.ContractsPerTx*GAS_PER_CONTRACT > blockGasLimit { - return fmt.Errorf("contracts per tx (%d) requires %d gas, exceeding block gas limit (%d)", - s.options.ContractsPerTx, s.options.ContractsPerTx*GAS_PER_CONTRACT, blockGasLimit) + if s.options.ContractsPerBlock*GAS_PER_CONTRACT > blockGasLimit { + return fmt.Errorf("contracts per block (%d) requires %d gas, exceeding block gas limit (%d)", + s.options.ContractsPerBlock, s.options.ContractsPerBlock*GAS_PER_CONTRACT, blockGasLimit) } - // Calculate throughput based on gas per block or contracts per tx - throughput := s.options.ContractsPerTx + // Calculate throughput based on gas per block or contracts per block + throughput := s.options.ContractsPerBlock if s.options.GasPerBlock > 0 { // Each deployment costs ~4.97M gas throughput = s.options.GasPerBlock / GAS_PER_CONTRACT @@ -162,8 +161,8 @@ func (s *Scenario) Run(ctx context.Context) error { s.logger.Infof("calculated throughput: %d contracts per block (target gas: %d)", throughput, s.options.GasPerBlock) } else { // Calculate gas needed for the specified number of contracts - totalGas := GAS_PER_CONTRACT * s.options.ContractsPerTx - s.logger.Infof("calculated gas: %d per tx for %d contracts", totalGas, throughput) + totalGas := GAS_PER_CONTRACT * s.options.ContractsPerBlock + s.logger.Infof("calculated gas: %d per block for %d contracts", totalGas, throughput) } initialRate := rate.Limit(float64(throughput) / float64(utils.SecondsPerSlot)) @@ -275,45 +274,20 @@ func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) auth.Nonce = big.NewInt(int64(wallet.GetNonce())) auth.Value = big.NewInt(0) - auth.GasLimit = 5000000 // Enough for 24kB contract + auth.GasLimit = GAS_PER_CONTRACT // Gas for single contract deployment auth.GasPrice = feeCap auth.GasTipCap = tipCap - // Get contract bytecode - bytecode := common.FromHex(contract.ContractBin) - - // Get ABI - parsed, err := contract.ContractMetaData.GetAbi() - if err != nil { - return nil, nil, nil, fmt.Errorf("failed to get ABI: %w", err) - } - - // Pack constructor arguments - packedArgs, err := parsed.Pack("", saltInt) - if err != nil { - return nil, nil, nil, fmt.Errorf("failed to pack constructor args: %w", err) - } - - // Combine bytecode and constructor args - fullBytecode := append(bytecode, packedArgs...) - - // Create transaction - tx := types.NewContractCreation(auth.Nonce.Uint64(), auth.Value, auth.GasLimit, auth.GasPrice, fullBytecode) - - // Sign transaction - signedTx, err := auth.Signer(auth.From, tx) - if err != nil { - return nil, nil, nil, fmt.Errorf("failed to sign transaction: %w", err) - } - - // Send transaction - err = client.SendTransactionCtx(ctx, signedTx) + // Deploy the StateBloatToken contract + address, tx, _, err := contract.DeployContract(auth, client.GetEthClient(), saltInt) if err != nil { - return nil, nil, nil, fmt.Errorf("failed to send transaction: %w", err) + return nil, nil, nil, fmt.Errorf("failed to deploy contract: %w", err) } // Update nonce wallet.SetNonce(wallet.GetNonce() + 1) - return signedTx, client, wallet, nil + // TODO: This should mention: Gas spent and bytes written. Also should give contract code hash for each contract. + s.logger.Infof("deployed contract at address: %s", address.Hex()) + return tx, client, wallet, nil } diff --git a/scenarios/statebloat/contract_deploy/contract_deploy_test.go b/scenarios/statebloat/contract_deploy/contract_deploy_test.go index 77b8be28..dcbe0f6a 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy_test.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy_test.go @@ -32,11 +32,9 @@ func TestContractDeploy(t *testing.T) { require.NoError(t, err) defer client.Close() - // Create context + // Create client pool ctx := context.Background() logger := logrus.New().WithField("test", "contract-deploy") - - // Create client pool clientPool := spamoor.NewClientPool(ctx, []string{"http://localhost:8545"}, logger) err = clientPool.PrepareClients() require.NoError(t, err) @@ -70,45 +68,107 @@ func TestContractDeploy(t *testing.T) { // Create scenario instance scenario := newScenario(logger) - // Configure scenario with 6 contracts per tx which is the maximum allowed by the latest fork. - config := ` + // Test case 1: Using contracts_per_block + t.Run("contracts_per_block", func(t *testing.T) { + // Initialize with contracts_per_block configuration + config := ` max_pending: 0 max_wallets: 1 rebroadcast: 30 base_fee: 20 tip_fee: 2 -gas_per_block: 30000000 +gas_per_block: 0 client_group: default -contracts_per_tx: 6 +contracts_per_block: 6 ` - err = scenario.Init(walletPool, config) - require.NoError(t, err) - - // Prepare wallets - err = walletPool.PrepareWallets(true) - require.NoError(t, err) - - // Create context with timeout - runCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() + require.NoError(t, scenario.Init(walletPool, config)) + + // Run scenario + runCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + + err := scenario.Run(runCtx) + require.NoError(t, err) + + // Verify contract deployment + block, err := client.BlockByNumber(runCtx, nil) + require.NoError(t, err) + assert.Greater(t, len(block.Transactions()), 0) + + // Check the first transaction + tx, _, err := client.TransactionByHash(runCtx, block.Transactions()[0].Hash()) + require.NoError(t, err) + receipt, err := client.TransactionReceipt(runCtx, tx.Hash()) + require.NoError(t, err) + assert.Equal(t, uint64(1), receipt.Status) + + // Verify contract was created + code, err := client.CodeAt(runCtx, receipt.ContractAddress, nil) + require.NoError(t, err) + assert.Greater(t, len(code), 0) + }) - // Run scenario - err = scenario.Run(runCtx) - require.NoError(t, err) + // Test case 2: Using gas_per_block + t.Run("gas_per_block", func(t *testing.T) { + // Initialize with gas_per_block configuration + config := ` +max_pending: 0 +max_wallets: 1 +rebroadcast: 30 +base_fee: 20 +tip_fee: 2 +gas_per_block: 30000000 +client_group: default +contracts_per_block: 0 +` + require.NoError(t, scenario.Init(walletPool, config)) + + // Run scenario + runCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + + err := scenario.Run(runCtx) + require.NoError(t, err) + + // Verify contract deployment + block, err := client.BlockByNumber(runCtx, nil) + require.NoError(t, err) + assert.Greater(t, len(block.Transactions()), 0) + + // Check the first transaction + tx, _, err := client.TransactionByHash(runCtx, block.Transactions()[0].Hash()) + require.NoError(t, err) + receipt, err := client.TransactionReceipt(runCtx, tx.Hash()) + require.NoError(t, err) + assert.Equal(t, uint64(1), receipt.Status) + + // Verify contract was created + code, err := client.CodeAt(runCtx, receipt.ContractAddress, nil) + require.NoError(t, err) + assert.Greater(t, len(code), 0) + }) - // Verify contract deployment - block, err := client.BlockByNumber(ctx, nil) - require.NoError(t, err) - assert.Greater(t, block.Transactions().Len(), 0) + // Test case 3: Invalid configuration + t.Run("invalid_config", func(t *testing.T) { + // Initialize with invalid configuration + config := ` +max_pending: 0 +max_wallets: 1 +rebroadcast: 30 +base_fee: 20 +tip_fee: 2 +gas_per_block: 0 +client_group: default +contracts_per_block: 0 +` + require.NoError(t, scenario.Init(walletPool, config)) - // Get transaction receipt - tx := block.Transactions()[0] - receipt, err := client.TransactionReceipt(ctx, tx.Hash()) - require.NoError(t, err) - assert.Equal(t, uint64(1), receipt.Status) + // Run scenario + runCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() - // Verify contract was created - code, err := client.CodeAt(ctx, receipt.ContractAddress, nil) - require.NoError(t, err) - assert.Greater(t, len(code), 0) + err := scenario.Run(runCtx) + require.Error(t, err) + assert.Contains(t, err.Error(), "neither gas per block limit nor contracts per block set") + }) } From 54337183d482a0a5688d207657cdbdb91fb72750 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 12 May 2025 12:54:19 +0200 Subject: [PATCH 09/39] fix(contract-deploy): Use 1559 fee config - Refactor gas fee parameters to align with EIP-1559 standards. - Initialize wallet pool in the contract deployment test. --- .../contract_deploy/contract_deploy.go | 46 ++++++++++--------- .../contract_deploy/contract_deploy_test.go | 4 ++ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index a49e3628..c3f79b47 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -241,25 +241,10 @@ func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) if client == nil { return nil, nil, nil, fmt.Errorf("no client available") } - - var feeCap *big.Int - var tipCap *big.Int - - if s.options.BaseFee > 0 { - feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) - } - if s.options.TipFee > 0 { - tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) + if wallet == nil { + return nil, nil, nil, fmt.Errorf("no wallet available") } - // Generate random salt for unique contract - salt := make([]byte, 32) - _, err := rand.Read(salt) - if err != nil { - return nil, nil, nil, fmt.Errorf("failed to generate salt: %w", err) - } - saltInt := new(big.Int).SetBytes(salt) - // Get chain ID chainId, err := client.GetChainId(ctx) if err != nil { @@ -275,11 +260,31 @@ func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) auth.Nonce = big.NewInt(int64(wallet.GetNonce())) auth.Value = big.NewInt(0) auth.GasLimit = GAS_PER_CONTRACT // Gas for single contract deployment - auth.GasPrice = feeCap - auth.GasTipCap = tipCap + + // Set EIP-1559 fee parameters + if s.options.BaseFee > 0 { + auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) + } + if s.options.TipFee > 0 { + auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) + } + + // Generate random salt for unique contract + salt := make([]byte, 32) + _, err = rand.Read(salt) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to generate salt: %w", err) + } + saltInt := new(big.Int).SetBytes(salt) + + // Ensure we have a valid client + ethClient := client.GetEthClient() + if ethClient == nil { + return nil, nil, nil, fmt.Errorf("failed to get eth client") + } // Deploy the StateBloatToken contract - address, tx, _, err := contract.DeployContract(auth, client.GetEthClient(), saltInt) + address, tx, _, err := contract.DeployContract(auth, ethClient, saltInt) if err != nil { return nil, nil, nil, fmt.Errorf("failed to deploy contract: %w", err) } @@ -287,7 +292,6 @@ func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) // Update nonce wallet.SetNonce(wallet.GetNonce() + 1) - // TODO: This should mention: Gas spent and bytes written. Also should give contract code hash for each contract. s.logger.Infof("deployed contract at address: %s", address.Hex()) return tx, client, wallet, nil } diff --git a/scenarios/statebloat/contract_deploy/contract_deploy_test.go b/scenarios/statebloat/contract_deploy/contract_deploy_test.go index dcbe0f6a..886eb0a8 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy_test.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy_test.go @@ -65,6 +65,10 @@ func TestContractDeploy(t *testing.T) { walletPool.SetRefillBalance(utils.EtherToWei(uint256.NewInt(1))) // 1 ETH walletPool.SetRefillInterval(60) + // Initialize wallet pool + err = walletPool.PrepareWallets(true) + require.NoError(t, err) + // Create scenario instance scenario := newScenario(logger) From 02affa8ecebdfd1f6ecbaa707e2f818265be40ec Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 12 May 2025 15:55:26 +0200 Subject: [PATCH 10/39] feat(contract-deploy): setup-teardown for tests - Introduced setup and teardown for contract deployment tests. - Updated scenario options to include a maximum transactions limit. St we can test for a single tx at a time and shortening testing time. --- .../contract_deploy/contract_deploy.go | 46 +++- .../contract_deploy/contract_deploy_test.go | 221 +++++++++++------- 2 files changed, 180 insertions(+), 87 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index c3f79b47..482ddc8f 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -38,6 +38,7 @@ type ScenarioOptions struct { GasPerBlock uint64 `yaml:"gas_per_block"` ClientGroup string `yaml:"client_group"` ContractsPerBlock uint64 `yaml:"contracts_per_block"` + MaxTransactions uint64 `yaml:"max_transactions"` // Maximum number of transactions to send (0 for unlimited) } type Scenario struct { @@ -53,12 +54,13 @@ var ScenarioName = "contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ MaxPending: 0, MaxWallets: 0, - Rebroadcast: 30, + Rebroadcast: 1, BaseFee: 20, TipFee: 2, GasPerBlock: 0, ClientGroup: "default", ContractsPerBlock: 1, + MaxTransactions: 0, // Default to unlimited } var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ Name: ScenarioName, @@ -82,6 +84,7 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.GasPerBlock, "gas-per-block", ScenarioDefaultOptions.GasPerBlock, "Target gas to use per block (will calculate number of contracts to deploy)") flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") flags.Uint64Var(&s.options.ContractsPerBlock, "contracts-per-block", ScenarioDefaultOptions.ContractsPerBlock, "Number of contracts to deploy per block") + flags.Uint64Var(&s.options.MaxTransactions, "max-transactions", ScenarioDefaultOptions.MaxTransactions, "Maximum number of transactions to send (0 for unlimited)") return nil } @@ -158,11 +161,21 @@ func (s *Scenario) Run(ctx context.Context) error { if throughput == 0 { throughput = 1 } - s.logger.Infof("calculated throughput: %d contracts per block (target gas: %d)", throughput, s.options.GasPerBlock) + s.logger.WithFields(logrus.Fields{ + "test": "contract-deploy", + "throughput": throughput, + "target_gas": s.options.GasPerBlock, + "gas_per_contract": GAS_PER_CONTRACT, + }).Info("calculated throughput") } else { // Calculate gas needed for the specified number of contracts totalGas := GAS_PER_CONTRACT * s.options.ContractsPerBlock - s.logger.Infof("calculated gas: %d per block for %d contracts", totalGas, throughput) + s.logger.WithFields(logrus.Fields{ + "test": "contract-deploy", + "total_gas": totalGas, + "contracts": s.options.ContractsPerBlock, + "gas_per_contract": GAS_PER_CONTRACT, + }).Info("calculated gas") } initialRate := rate.Limit(float64(throughput) / float64(utils.SecondsPerSlot)) @@ -172,6 +185,12 @@ func (s *Scenario) Run(ctx context.Context) error { limiter := rate.NewLimiter(initialRate, 1) for { + // Check if we've reached the maximum number of transactions + if s.options.MaxTransactions > 0 && txIdxCounter >= s.options.MaxTransactions { + s.logger.Infof("reached maximum number of transactions (%d)", s.options.MaxTransactions) + break + } + if err := limiter.Wait(ctx); err != nil { if ctx.Err() != nil { break @@ -223,13 +242,16 @@ func (s *Scenario) Run(ctx context.Context) error { } txCount.Add(1) - logger.Infof("sent tx #%6d: %v", txIdx+1, tx.Hash().String()) }(txIdx, lastChan, currentChan) lastChan = currentChan } s.pendingWGroup.Wait() - s.logger.Infof("finished sending transactions, awaiting block inclusion...") + s.logger.WithFields(logrus.Fields{ + "test": "contract-deploy", + "total_txs": txCount.Load(), + "pending_txs": pendingCount.Load(), + }).Info("finished sending transactions, awaiting block inclusion...") return nil } @@ -292,6 +314,18 @@ func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) // Update nonce wallet.SetNonce(wallet.GetNonce() + 1) - s.logger.Infof("deployed contract at address: %s", address.Hex()) + // Calculate bytes written and gas/byte ratio + txBytes := len(tx.Data()) + gasPerByte := float64(GAS_PER_CONTRACT) / float64(txBytes) + + s.logger.WithFields(logrus.Fields{ + "test": "contract-deploy", + "tx_hash": tx.Hash().Hex(), + "contract_address": address.Hex(), + "bytes_written": txBytes, + "gas_per_byte": fmt.Sprintf("%.2f", gasPerByte), + "contracts": 1, + }).Info("deployed contract") + return tx, client, wallet, nil } diff --git a/scenarios/statebloat/contract_deploy/contract_deploy_test.go b/scenarios/statebloat/contract_deploy/contract_deploy_test.go index 886eb0a8..653bd50d 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy_test.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy_test.go @@ -12,17 +12,30 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/common" "github.com/ethpandaops/spamoor/spamoor" "github.com/ethpandaops/spamoor/txbuilder" "github.com/ethpandaops/spamoor/utils" ) -func TestContractDeploy(t *testing.T) { +type testFixture struct { + t *testing.T + cmd *exec.Cmd + client *ethclient.Client + ctx context.Context + logger *logrus.Entry + clientPool *spamoor.ClientPool + rootWallet *txbuilder.Wallet + txpool *txbuilder.TxPool + walletPool *spamoor.WalletPool + scenario *Scenario +} + +func setupTestFixture(t *testing.T) *testFixture { // Start Anvil server with legacy transactions cmd := exec.Command("anvil", "--hardfork", "pectra") err := cmd.Start() require.NoError(t, err) - defer cmd.Process.Kill() // Wait for Anvil to start time.Sleep(2 * time.Second) @@ -30,7 +43,6 @@ func TestContractDeploy(t *testing.T) { // Connect to Anvil client, err := ethclient.Dial("http://localhost:8545") require.NoError(t, err) - defer client.Close() // Create client pool ctx := context.Background() @@ -70,109 +82,156 @@ func TestContractDeploy(t *testing.T) { require.NoError(t, err) // Create scenario instance - scenario := newScenario(logger) + scenario := newScenario(logger).(*Scenario) + + return &testFixture{ + t: t, + cmd: cmd, + client: client, + ctx: ctx, + logger: logger, + clientPool: clientPool, + rootWallet: rootWallet, + txpool: txpool, + walletPool: walletPool, + scenario: scenario, + } +} + +func (f *testFixture) teardown() { + if f.cmd != nil && f.cmd.Process != nil { + f.cmd.Process.Kill() + } + if f.client != nil { + f.client.Close() + } +} + +func (f *testFixture) verifyContractDeployment(runCtx context.Context) { + // Verify contract deployment + block, err := f.client.BlockByNumber(runCtx, nil) + require.NoError(f.t, err) + assert.Greater(f.t, len(block.Transactions()), 0) + + // Get the expected number of contracts based on scenario config + expectedContracts := f.scenario.options.ContractsPerBlock + if f.scenario.options.GasPerBlock > 0 { + expectedContracts = f.scenario.options.GasPerBlock / GAS_PER_CONTRACT + if expectedContracts == 0 { + expectedContracts = 1 + } + } + + // Track deployed contracts + deployedContracts := 0 + contractAddresses := make([]common.Address, 0) + + // Check all transactions in the block + for _, tx := range block.Transactions() { + receipt, err := f.client.TransactionReceipt(runCtx, tx.Hash()) + require.NoError(f.t, err) + assert.Equal(f.t, uint64(1), receipt.Status) + + // If this is a contract creation transaction + if receipt.ContractAddress != (common.Address{}) { + deployedContracts++ + contractAddresses = append(contractAddresses, receipt.ContractAddress) + } + } + + // Verify the number of contracts deployed matches the expected count + assert.Equal(f.t, expectedContracts, deployedContracts, "Number of deployed contracts should match the scenario configuration") + + // Verify each contract's size + for _, addr := range contractAddresses { + code, err := f.client.CodeAt(runCtx, addr, nil) + require.NoError(f.t, err) + + // EIP-170 limit is 24,576 bytes (0x6000) + assert.Equal(f.t, 24576, len(code), "Contract code size should be exactly 24,576 bytes (EIP-170 limit)") + } + + f.logger.WithFields(logrus.Fields{ + "expected_contracts": expectedContracts, + "deployed_contracts": deployedContracts, + "contract_addresses": contractAddresses, + }).Info("Verified contract deployments") +} - // Test case 1: Using contracts_per_block - t.Run("contracts_per_block", func(t *testing.T) { - // Initialize with contracts_per_block configuration - config := ` +func TestContractDeployWithContractsPerBlock(t *testing.T) { + fixture := setupTestFixture(t) + defer fixture.teardown() + + // Initialize with contracts_per_block configuration + config := ` max_pending: 0 max_wallets: 1 -rebroadcast: 30 +rebroadcast: 2 base_fee: 20 tip_fee: 2 gas_per_block: 0 client_group: default contracts_per_block: 6 +max_transactions: 1 ` - require.NoError(t, scenario.Init(walletPool, config)) - - // Run scenario - runCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() - - err := scenario.Run(runCtx) - require.NoError(t, err) - - // Verify contract deployment - block, err := client.BlockByNumber(runCtx, nil) - require.NoError(t, err) - assert.Greater(t, len(block.Transactions()), 0) - - // Check the first transaction - tx, _, err := client.TransactionByHash(runCtx, block.Transactions()[0].Hash()) - require.NoError(t, err) - receipt, err := client.TransactionReceipt(runCtx, tx.Hash()) - require.NoError(t, err) - assert.Equal(t, uint64(1), receipt.Status) - - // Verify contract was created - code, err := client.CodeAt(runCtx, receipt.ContractAddress, nil) - require.NoError(t, err) - assert.Greater(t, len(code), 0) - }) + require.NoError(t, fixture.scenario.Init(fixture.walletPool, config)) + + // Run scenario + runCtx, cancel := context.WithTimeout(fixture.ctx, 30*time.Second) + defer cancel() - // Test case 2: Using gas_per_block - t.Run("gas_per_block", func(t *testing.T) { - // Initialize with gas_per_block configuration - config := ` + err := fixture.scenario.Run(runCtx) + require.NoError(t, err) + + fixture.verifyContractDeployment(runCtx) +} + +func TestContractDeployWithGasPerBlock(t *testing.T) { + fixture := setupTestFixture(t) + defer fixture.teardown() + + // Initialize with gas_per_block configuration + config := ` max_pending: 0 max_wallets: 1 -rebroadcast: 30 +rebroadcast: 2 base_fee: 20 tip_fee: 2 gas_per_block: 30000000 client_group: default contracts_per_block: 0 +max_transactions: 1 ` - require.NoError(t, scenario.Init(walletPool, config)) - - // Run scenario - runCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() - - err := scenario.Run(runCtx) - require.NoError(t, err) - - // Verify contract deployment - block, err := client.BlockByNumber(runCtx, nil) - require.NoError(t, err) - assert.Greater(t, len(block.Transactions()), 0) - - // Check the first transaction - tx, _, err := client.TransactionByHash(runCtx, block.Transactions()[0].Hash()) - require.NoError(t, err) - receipt, err := client.TransactionReceipt(runCtx, tx.Hash()) - require.NoError(t, err) - assert.Equal(t, uint64(1), receipt.Status) - - // Verify contract was created - code, err := client.CodeAt(runCtx, receipt.ContractAddress, nil) - require.NoError(t, err) - assert.Greater(t, len(code), 0) - }) + require.NoError(t, fixture.scenario.Init(fixture.walletPool, config)) + + // Run scenario + runCtx, cancel := context.WithTimeout(fixture.ctx, 30*time.Second) + defer cancel() + + err := fixture.scenario.Run(runCtx) + require.NoError(t, err) - // Test case 3: Invalid configuration - t.Run("invalid_config", func(t *testing.T) { - // Initialize with invalid configuration - config := ` + fixture.verifyContractDeployment(runCtx) +} + +func TestContractDeployWithInvalidConfig(t *testing.T) { + fixture := setupTestFixture(t) + defer fixture.teardown() + + // Initialize with invalid configuration + config := ` max_pending: 0 max_wallets: 1 -rebroadcast: 30 +rebroadcast: 1 base_fee: 20 tip_fee: 2 gas_per_block: 0 client_group: default contracts_per_block: 0 +max_transactions: 1 ` - require.NoError(t, scenario.Init(walletPool, config)) - - // Run scenario - runCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() - - err := scenario.Run(runCtx) - require.Error(t, err) - assert.Contains(t, err.Error(), "neither gas per block limit nor contracts per block set") - }) + // We expect Init to fail with this configuration + err := fixture.scenario.Init(fixture.walletPool, config) + require.Error(t, err) + assert.Contains(t, err.Error(), "neither gas per block limit nor contracts per block set") } From 09241822eebf27681a2f0d29185c614c286a8e40 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Tue, 13 May 2025 23:40:11 +0200 Subject: [PATCH 11/39] feat(contract-deploy): add dummy functions to increase bytecode size to max (EIP170) - Introduced multiple dummy functions in the StateBloatToken contract to artificially inflate bytecode size. - Updated ABI and binary files to reflect changes in the contract structure. --- .../contract/StateBloatToken.abi | 2 +- .../contract/StateBloatToken.bin | 2 +- .../contract/StateBloatToken.go | 2728 ++++++++++++++++- .../contract/StateBloatToken.sol | 568 +++- 4 files changed, 3294 insertions(+), 6 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi index fb9e7b53..4dea8206 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi @@ -1 +1 @@ -[{"inputs":[{"internalType":"uint256","name":"_salt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"inputs":[{"internalType":"uint256","name":"_salt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dummy1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy10","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy11","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy12","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy13","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy14","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy15","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy16","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy17","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy19","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy21","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy22","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy23","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy24","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy25","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy26","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy27","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy28","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy29","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy30","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy31","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy32","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy33","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy34","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy35","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy36","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy37","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy38","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy39","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy4","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy40","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy41","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy42","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy43","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy44","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy45","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy46","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy47","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy48","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy49","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy5","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy50","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy51","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy52","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy53","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy54","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy55","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy56","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy57","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy58","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy59","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy6","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy60","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy61","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy62","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy63","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy64","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy65","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy66","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy67","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy68","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy69","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy7","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy70","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy71","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy72","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy73","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy74","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy75","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy8","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy9","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom1","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom10","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom11","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom12","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom13","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom14","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom15","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom16","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom17","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom18","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom19","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom2","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom3","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom4","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom5","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom6","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom7","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom8","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom9","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin index 0ea68c09..10e9b41a 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin @@ -1 +1 @@ -60a060405234801561000f575f5ffd5b50604051611503380380611503833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b608051610dae6107555f395f6108cf0152610dae5ff3fe608060405234801561000f575f5ffd5b506004361061009c575f3560e01c806370a082311161006457806370a082311461015a57806395d89b411461018a578063a9059cbb146101a8578063bfa0b133146101d8578063dd62ed3e146101f65761009c565b806306fdde03146100a0578063095ea7b3146100be57806318160ddd146100ee57806323b872dd1461010c578063313ce5671461013c575b5f5ffd5b6100a8610226565b6040516100b59190610981565b60405180910390f35b6100d860048036038101906100d39190610a32565b6102b1565b6040516100e59190610a8a565b60405180910390f35b6100f661039e565b6040516101039190610ab2565b60405180910390f35b61012660048036038101906101219190610acb565b6103a4565b6040516101339190610a8a565b60405180910390f35b610144610684565b6040516101519190610b36565b60405180910390f35b610174600480360381019061016f9190610b4f565b610696565b6040516101819190610ab2565b60405180910390f35b6101926106ab565b60405161019f9190610981565b60405180910390f35b6101c260048036038101906101bd9190610a32565b610737565b6040516101cf9190610a8a565b60405180910390f35b6101e06108cd565b6040516101ed9190610ab2565b60405180910390f35b610210600480360381019061020b9190610b7a565b6108f1565b60405161021d9190610ab2565b60405180910390f35b5f805461023290610be5565b80601f016020809104026020016040519081016040528092919081815260200182805461025e90610be5565b80156102a95780601f10610280576101008083540402835291602001916102a9565b820191905f5260205f20905b81548152906001019060200180831161028c57829003601f168201915b505050505081565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161038c9190610ab2565b60405180910390a36001905092915050565b60035481565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041c90610c5f565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156104e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d790610cc7565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461052c9190610d12565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461057f9190610d45565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461060d9190610d12565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516106719190610ab2565b60405180910390a3600190509392505050565b60025f9054906101000a900460ff1681565b6004602052805f5260405f205f915090505481565b600180546106b890610be5565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490610be5565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b505050505081565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156107b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107af90610c5f565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108049190610d12565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108579190610d45565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516108bb9190610ab2565b60405180910390a36001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61095382610911565b61095d818561091b565b935061096d81856020860161092b565b61097681610939565b840191505092915050565b5f6020820190508181035f8301526109998184610949565b905092915050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6109ce826109a5565b9050919050565b6109de816109c4565b81146109e8575f5ffd5b50565b5f813590506109f9816109d5565b92915050565b5f819050919050565b610a11816109ff565b8114610a1b575f5ffd5b50565b5f81359050610a2c81610a08565b92915050565b5f5f60408385031215610a4857610a476109a1565b5b5f610a55858286016109eb565b9250506020610a6685828601610a1e565b9150509250929050565b5f8115159050919050565b610a8481610a70565b82525050565b5f602082019050610a9d5f830184610a7b565b92915050565b610aac816109ff565b82525050565b5f602082019050610ac55f830184610aa3565b92915050565b5f5f5f60608486031215610ae257610ae16109a1565b5b5f610aef868287016109eb565b9350506020610b00868287016109eb565b9250506040610b1186828701610a1e565b9150509250925092565b5f60ff82169050919050565b610b3081610b1b565b82525050565b5f602082019050610b495f830184610b27565b92915050565b5f60208284031215610b6457610b636109a1565b5b5f610b71848285016109eb565b91505092915050565b5f5f60408385031215610b9057610b8f6109a1565b5b5f610b9d858286016109eb565b9250506020610bae858286016109eb565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610bfc57607f821691505b602082108103610c0f57610c0e610bb8565b5b50919050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f610c4960148361091b565b9150610c5482610c15565b602082019050919050565b5f6020820190508181035f830152610c7681610c3d565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f610cb160168361091b565b9150610cbc82610c7d565b602082019050919050565b5f6020820190508181035f830152610cde81610ca5565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610d1c826109ff565b9150610d27836109ff565b9250828203905081811115610d3f57610d3e610ce5565b5b92915050565b5f610d4f826109ff565b9150610d5a836109ff565b9250828201905080821115610d7257610d71610ce5565b5b9291505056fea26469706673582212207182ee741671c2a140c5eb4e62cb72b950c446fa68846143d961b62f544f59c764736f6c634300081e0033 \ No newline at end of file +60a060405234801561000f575f5ffd5b50604051615fd4380380615fd4833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b60805161587f6107555f395f614a7b015261587f5ff3fe608060405234801561000f575f5ffd5b5060043610610606575f3560e01c8063657b6ef711610319578063b1802b9a116101a6578063d9bb3174116100f2578063f26c779b116100ab578063f8716f1411610085578063f8716f1414611360578063faf35ced1461137e578063fe7d5996146113ae578063ffbf0469146113cc57610606565b8063f26c779b14611306578063f4978b0414611324578063f5f573811461134257610606565b8063d9bb31741461122e578063dc1d8a9b1461124c578063dd62ed3e1461126a578063e2d275301461129a578063e8c927b3146112b8578063eb4329c8146112d657610606565b8063bbe231321161015f578063c958d4bf11610139578063c958d4bf146111b6578063cfd66863146111d4578063d101dcd0146111f2578063d74194691461121057610606565b8063bbe231321461114a578063bfa0b13314611168578063c2be97e31461118657610606565b8063b1802b9a14611072578063b2bb360e146110a2578063b4c48668146110c0578063b66dd750146110de578063b9a6d645146110fc578063bb9bfe061461111a57610606565b80637e544937116102655780639c5dfe731161021e578063a9059cbb116101f8578063a9059cbb14610fd6578063aaa7af7014611006578063acc5aee914611024578063ad8f42211461105457610606565b80639c5dfe7314610f7c5780639df61a2514610f9a578063a891d4d414610fb857610606565b80637e54493714610eb65780637f34d94b14610ed45780638619d60714610ef25780638789ca6714610f105780638f4a840614610f4057806395d89b4114610f5e57610606565b806374f83d02116102d25780637a319c18116102ac5780637a319c1814610e2c5780637c66673e14610e4a5780637c72ed0d14610e7a5780637dffdc3214610e9857610606565b806374f83d0214610dd257806377c0209e14610df0578063792c7f3e14610e0e57610606565b8063657b6ef714610ce8578063672151fe14610d185780636abceacd14610d365780636c12ed2814610d5457806370a0823114610d8457806374e73fd314610db457610606565b8063313ce567116104975780634b3c7f5f116103e357806358b6a9bd1161039c57806361b970eb1161037657806361b970eb14610c70578063639ec53a14610c8e5780636547317414610cac5780636578534c14610cca57610606565b806358b6a9bd14610c16578063595471b814610c345780635af92c0514610c5257610606565b80634b3c7f5f14610b3e5780634e1dbb8214610b5c5780634f5e555714610b7a5780634f7bd75a14610b9857806354c2792014610bc8578063552a1b5614610be657610606565b80633ea117ce1161045057806342937dbd1161042a57806342937dbd14610ab457806343a6b92d14610ad257806344050a2814610af05780634a2e93c614610b2057610606565b80633ea117ce14610a5a5780634128a85d14610a78578063418b181614610a9657610606565b8063313ce5671461098257806334517f0b146109a0578063378c5382146109be57806339e0bd12146109dc5780633a13199014610a0c5780633b6be45914610a3c57610606565b80631bbffe6f1161055657806321ecd7a31161050f5780632545d8b7116104e95780632545d8b7146108f85780632787325b14610916578063291c3bd7146109345780633125f37a1461096457610606565b806321ecd7a31461088c578063239af2a5146108aa57806323b872dd146108c857610606565b80631bbffe6f146107c65780631d527cde146107f65780631eaa7c52146108145780631f29783f146108325780631f449589146108505780631fd298ec1461086e57610606565b806312901b42116105c357806318160ddd1161059d57806318160ddd1461073c57806319cf6a911461075a5780631a97f18e146107785780631b17c65c1461079657610606565b806312901b42146106e257806313ebb5ec1461070057806316a3045b1461071e57610606565b80630460faf61461060a57806306fdde031461063a5780630717b16114610658578063095ea7b3146106765780630cb7a9e7146106a65780631215a3ab146106c4575b5f5ffd5b610624600480360381019061061f91906153a3565b6113ea565b604051610631919061540d565b60405180910390f35b6106426116ca565b60405161064f9190615496565b60405180910390f35b610660611755565b60405161066d91906154c5565b60405180910390f35b610690600480360381019061068b91906154de565b61175d565b60405161069d919061540d565b60405180910390f35b6106ae61184a565b6040516106bb91906154c5565b60405180910390f35b6106cc611852565b6040516106d991906154c5565b60405180910390f35b6106ea61185a565b6040516106f791906154c5565b60405180910390f35b610708611862565b60405161071591906154c5565b60405180910390f35b61072661186a565b60405161073391906154c5565b60405180910390f35b610744611872565b60405161075191906154c5565b60405180910390f35b610762611878565b60405161076f91906154c5565b60405180910390f35b610780611880565b60405161078d91906154c5565b60405180910390f35b6107b060048036038101906107ab91906153a3565b611888565b6040516107bd919061540d565b60405180910390f35b6107e060048036038101906107db91906153a3565b611b68565b6040516107ed919061540d565b60405180910390f35b6107fe611e48565b60405161080b91906154c5565b60405180910390f35b61081c611e50565b60405161082991906154c5565b60405180910390f35b61083a611e58565b60405161084791906154c5565b60405180910390f35b610858611e60565b60405161086591906154c5565b60405180910390f35b610876611e68565b60405161088391906154c5565b60405180910390f35b610894611e70565b6040516108a191906154c5565b60405180910390f35b6108b2611e78565b6040516108bf91906154c5565b60405180910390f35b6108e260048036038101906108dd91906153a3565b611e80565b6040516108ef919061540d565b60405180910390f35b610900612160565b60405161090d91906154c5565b60405180910390f35b61091e612168565b60405161092b91906154c5565b60405180910390f35b61094e600480360381019061094991906153a3565b612170565b60405161095b919061540d565b60405180910390f35b61096c612450565b60405161097991906154c5565b60405180910390f35b61098a612458565b6040516109979190615537565b60405180910390f35b6109a861246a565b6040516109b591906154c5565b60405180910390f35b6109c6612472565b6040516109d391906154c5565b60405180910390f35b6109f660048036038101906109f191906153a3565b61247a565b604051610a03919061540d565b60405180910390f35b610a266004803603810190610a2191906153a3565b61275a565b604051610a33919061540d565b60405180910390f35b610a44612a3a565b604051610a5191906154c5565b60405180910390f35b610a62612a42565b604051610a6f91906154c5565b60405180910390f35b610a80612a4a565b604051610a8d91906154c5565b60405180910390f35b610a9e612a52565b604051610aab91906154c5565b60405180910390f35b610abc612a5a565b604051610ac991906154c5565b60405180910390f35b610ada612a62565b604051610ae791906154c5565b60405180910390f35b610b0a6004803603810190610b0591906153a3565b612a6a565b604051610b17919061540d565b60405180910390f35b610b28612d4a565b604051610b3591906154c5565b60405180910390f35b610b46612d52565b604051610b5391906154c5565b60405180910390f35b610b64612d5a565b604051610b7191906154c5565b60405180910390f35b610b82612d62565b604051610b8f91906154c5565b60405180910390f35b610bb26004803603810190610bad91906153a3565b612d6a565b604051610bbf919061540d565b60405180910390f35b610bd061304a565b604051610bdd91906154c5565b60405180910390f35b610c006004803603810190610bfb91906153a3565b613052565b604051610c0d919061540d565b60405180910390f35b610c1e613332565b604051610c2b91906154c5565b60405180910390f35b610c3c61333a565b604051610c4991906154c5565b60405180910390f35b610c5a613342565b604051610c6791906154c5565b60405180910390f35b610c7861334a565b604051610c8591906154c5565b60405180910390f35b610c96613352565b604051610ca391906154c5565b60405180910390f35b610cb461335a565b604051610cc191906154c5565b60405180910390f35b610cd2613362565b604051610cdf91906154c5565b60405180910390f35b610d026004803603810190610cfd91906153a3565b61336a565b604051610d0f919061540d565b60405180910390f35b610d2061364a565b604051610d2d91906154c5565b60405180910390f35b610d3e613652565b604051610d4b91906154c5565b60405180910390f35b610d6e6004803603810190610d6991906153a3565b61365a565b604051610d7b919061540d565b60405180910390f35b610d9e6004803603810190610d999190615550565b61393a565b604051610dab91906154c5565b60405180910390f35b610dbc61394f565b604051610dc991906154c5565b60405180910390f35b610dda613957565b604051610de791906154c5565b60405180910390f35b610df861395f565b604051610e0591906154c5565b60405180910390f35b610e16613967565b604051610e2391906154c5565b60405180910390f35b610e3461396f565b604051610e4191906154c5565b60405180910390f35b610e646004803603810190610e5f91906153a3565b613977565b604051610e71919061540d565b60405180910390f35b610e82613c57565b604051610e8f91906154c5565b60405180910390f35b610ea0613c5f565b604051610ead91906154c5565b60405180910390f35b610ebe613c67565b604051610ecb91906154c5565b60405180910390f35b610edc613c6f565b604051610ee991906154c5565b60405180910390f35b610efa613c77565b604051610f0791906154c5565b60405180910390f35b610f2a6004803603810190610f2591906153a3565b613c7f565b604051610f37919061540d565b60405180910390f35b610f48613f5f565b604051610f5591906154c5565b60405180910390f35b610f66613f67565b604051610f739190615496565b60405180910390f35b610f84613ff3565b604051610f9191906154c5565b60405180910390f35b610fa2613ffb565b604051610faf91906154c5565b60405180910390f35b610fc0614003565b604051610fcd91906154c5565b60405180910390f35b610ff06004803603810190610feb91906154de565b61400b565b604051610ffd919061540d565b60405180910390f35b61100e6141a1565b60405161101b91906154c5565b60405180910390f35b61103e600480360381019061103991906153a3565b6141a9565b60405161104b919061540d565b60405180910390f35b61105c614489565b60405161106991906154c5565b60405180910390f35b61108c600480360381019061108791906153a3565b614491565b604051611099919061540d565b60405180910390f35b6110aa614771565b6040516110b791906154c5565b60405180910390f35b6110c8614779565b6040516110d591906154c5565b60405180910390f35b6110e6614781565b6040516110f391906154c5565b60405180910390f35b611104614789565b60405161111191906154c5565b60405180910390f35b611134600480360381019061112f91906153a3565b614791565b604051611141919061540d565b60405180910390f35b611152614a71565b60405161115f91906154c5565b60405180910390f35b611170614a79565b60405161117d91906154c5565b60405180910390f35b6111a0600480360381019061119b91906153a3565b614a9d565b6040516111ad919061540d565b60405180910390f35b6111be614d7d565b6040516111cb91906154c5565b60405180910390f35b6111dc614d85565b6040516111e991906154c5565b60405180910390f35b6111fa614d8d565b60405161120791906154c5565b60405180910390f35b611218614d95565b60405161122591906154c5565b60405180910390f35b611236614d9d565b60405161124391906154c5565b60405180910390f35b611254614da5565b60405161126191906154c5565b60405180910390f35b611284600480360381019061127f919061557b565b614dad565b60405161129191906154c5565b60405180910390f35b6112a2614dcd565b6040516112af91906154c5565b60405180910390f35b6112c0614dd5565b6040516112cd91906154c5565b60405180910390f35b6112f060048036038101906112eb91906153a3565b614ddd565b6040516112fd919061540d565b60405180910390f35b61130e615002565b60405161131b91906154c5565b60405180910390f35b61132c61500a565b60405161133991906154c5565b60405180910390f35b61134a615012565b60405161135791906154c5565b60405180910390f35b61136861501a565b60405161137591906154c5565b60405180910390f35b611398600480360381019061139391906153a3565b615022565b6040516113a5919061540d565b60405180910390f35b6113b6615302565b6040516113c391906154c5565b60405180910390f35b6113d461530a565b6040516113e191906154c5565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561146b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461157291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546115c591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461165391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516116b791906154c5565b60405180910390a3600190509392505050565b5f80546116d690615749565b80601f016020809104026020016040519081016040528092919081815260200182805461170290615749565b801561174d5780601f106117245761010080835404028352916020019161174d565b820191905f5260205f20905b81548152906001019060200180831161173057829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161183891906154c5565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190090615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156119c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bb9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611a1091906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611a6391906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611af191906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611b5591906154c5565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9b9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611cf091906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611d4391906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611dd191906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611e3591906154c5565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6048905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb39061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461200891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461205b91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546120e991906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161214d91906154c5565b60405180910390a3600190509392505050565b5f6001905090565b5f6045905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156121f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e8906157c3565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156122ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a39061582b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546122f891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461234b91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546123d991906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161243d91906154c5565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f604b905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156124fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156125b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ad9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461260291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461265591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546126e391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161274791906154c5565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156127db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546128e291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461293591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546129c391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612a2791906154c5565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612aeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ba6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612bf291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612c4591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612cd391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612d3791906154c5565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612de290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ea6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ef291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612f4591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612fd391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161303791906154c5565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156130d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ca90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561318e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131859061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546131da91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461322d91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546132bb91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161331f91906154c5565b60405180910390a3600190509392505050565b5f6009905090565b5f6049905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f6043905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156133eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133e2906157c3565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156134a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349d9061582b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546134f291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461354591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135d391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161363791906154c5565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156136db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136d290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161378d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546137e291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461383591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546138c391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161392791906154c5565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156139f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139ef90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613ab3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613aaa9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613aff91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613b5291906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613be091906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613c4491906154c5565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613d00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613cf790615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613db29061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e0791906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e5a91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ee891906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613f4c91906154c5565b60405180910390a3600190509392505050565b5f600b905090565b60018054613f7490615749565b80601f0160208091040260200160405190810160405280929190818152602001828054613fa090615749565b8015613feb5780601f10613fc257610100808354040283529160200191613feb565b820191905f5260205f20905b815481529060010190602001808311613fce57829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561408c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161408390615603565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546140d891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461412b91906156e9565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161418f91906154c5565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561422a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161422190615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156142e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016142dc9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461433191906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461438491906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461441291906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161447691906154c5565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161450990615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156145cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016145c49061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461461991906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461466c91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146fa91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161475e91906154c5565b60405180910390a3600190509392505050565b5f6018905090565b5f604a905090565b5f600f905090565b5f6044905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161480990615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156148cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148c49061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461491991906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461496c91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546149fa91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614a5e91906154c5565b60405180910390a3600190509392505050565b5f6046905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614b1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614b1590615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614bd09061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c2591906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c7891906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d0691906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614d6a91906154c5565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6042905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614e55906157c3565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614eaa91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614efd91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f8b91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614fef91906154c5565b60405180910390a3600190509392505050565b5f6007905090565b5f6047905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156150a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161509a90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561515e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016151559061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546151aa91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546151fd91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461528b91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516152ef91906154c5565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61533f82615316565b9050919050565b61534f81615335565b8114615359575f5ffd5b50565b5f8135905061536a81615346565b92915050565b5f819050919050565b61538281615370565b811461538c575f5ffd5b50565b5f8135905061539d81615379565b92915050565b5f5f5f606084860312156153ba576153b9615312565b5b5f6153c78682870161535c565b93505060206153d88682870161535c565b92505060406153e98682870161538f565b9150509250925092565b5f8115159050919050565b615407816153f3565b82525050565b5f6020820190506154205f8301846153fe565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61546882615426565b6154728185615430565b9350615482818560208601615440565b61548b8161544e565b840191505092915050565b5f6020820190508181035f8301526154ae818461545e565b905092915050565b6154bf81615370565b82525050565b5f6020820190506154d85f8301846154b6565b92915050565b5f5f604083850312156154f4576154f3615312565b5b5f6155018582860161535c565b92505060206155128582860161538f565b9150509250929050565b5f60ff82169050919050565b6155318161551c565b82525050565b5f60208201905061554a5f830184615528565b92915050565b5f6020828403121561556557615564615312565b5b5f6155728482850161535c565b91505092915050565b5f5f6040838503121561559157615590615312565b5b5f61559e8582860161535c565b92505060206155af8582860161535c565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6155ed601483615430565b91506155f8826155b9565b602082019050919050565b5f6020820190508181035f83015261561a816155e1565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f615655601683615430565b915061566082615621565b602082019050919050565b5f6020820190508181035f83015261568281615649565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6156c082615370565b91506156cb83615370565b92508282039050818111156156e3576156e2615689565b5b92915050565b5f6156f382615370565b91506156fe83615370565b925082820190508082111561571657615715615689565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061576057607f821691505b6020821081036157735761577261571c565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6157ad600183615430565b91506157b882615779565b602082019050919050565b5f6020820190508181035f8301526157da816157a1565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f615815600183615430565b9150615820826157e1565b602082019050919050565b5f6020820190508181035f83015261584281615809565b905091905056fea2646970667358221220ce03f2ea0f8ec341a07b9c0512b41f44d879b740c55b3572c5707216663e8a3f64736f6c634300081e0033 \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go index bfb58592..f744e474 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go @@ -31,8 +31,8 @@ var ( // ContractMetaData contains all meta data concerning the Contract contract. var ContractMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"salt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561000f575f5ffd5b50604051611503380380611503833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b608051610dae6107555f395f6108cf0152610dae5ff3fe608060405234801561000f575f5ffd5b506004361061009c575f3560e01c806370a082311161006457806370a082311461015a57806395d89b411461018a578063a9059cbb146101a8578063bfa0b133146101d8578063dd62ed3e146101f65761009c565b806306fdde03146100a0578063095ea7b3146100be57806318160ddd146100ee57806323b872dd1461010c578063313ce5671461013c575b5f5ffd5b6100a8610226565b6040516100b59190610981565b60405180910390f35b6100d860048036038101906100d39190610a32565b6102b1565b6040516100e59190610a8a565b60405180910390f35b6100f661039e565b6040516101039190610ab2565b60405180910390f35b61012660048036038101906101219190610acb565b6103a4565b6040516101339190610a8a565b60405180910390f35b610144610684565b6040516101519190610b36565b60405180910390f35b610174600480360381019061016f9190610b4f565b610696565b6040516101819190610ab2565b60405180910390f35b6101926106ab565b60405161019f9190610981565b60405180910390f35b6101c260048036038101906101bd9190610a32565b610737565b6040516101cf9190610a8a565b60405180910390f35b6101e06108cd565b6040516101ed9190610ab2565b60405180910390f35b610210600480360381019061020b9190610b7a565b6108f1565b60405161021d9190610ab2565b60405180910390f35b5f805461023290610be5565b80601f016020809104026020016040519081016040528092919081815260200182805461025e90610be5565b80156102a95780601f10610280576101008083540402835291602001916102a9565b820191905f5260205f20905b81548152906001019060200180831161028c57829003601f168201915b505050505081565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161038c9190610ab2565b60405180910390a36001905092915050565b60035481565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015610425576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041c90610c5f565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156104e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d790610cc7565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461052c9190610d12565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461057f9190610d45565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461060d9190610d12565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516106719190610ab2565b60405180910390a3600190509392505050565b60025f9054906101000a900460ff1681565b6004602052805f5260405f205f915090505481565b600180546106b890610be5565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490610be5565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b505050505081565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156107b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107af90610c5f565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108049190610d12565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546108579190610d45565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516108bb9190610ab2565b60405180910390a36001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61095382610911565b61095d818561091b565b935061096d81856020860161092b565b61097681610939565b840191505092915050565b5f6020820190508181035f8301526109998184610949565b905092915050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6109ce826109a5565b9050919050565b6109de816109c4565b81146109e8575f5ffd5b50565b5f813590506109f9816109d5565b92915050565b5f819050919050565b610a11816109ff565b8114610a1b575f5ffd5b50565b5f81359050610a2c81610a08565b92915050565b5f5f60408385031215610a4857610a476109a1565b5b5f610a55858286016109eb565b9250506020610a6685828601610a1e565b9150509250929050565b5f8115159050919050565b610a8481610a70565b82525050565b5f602082019050610a9d5f830184610a7b565b92915050565b610aac816109ff565b82525050565b5f602082019050610ac55f830184610aa3565b92915050565b5f5f5f60608486031215610ae257610ae16109a1565b5b5f610aef868287016109eb565b9350506020610b00868287016109eb565b9250506040610b1186828701610a1e565b9150509250925092565b5f60ff82169050919050565b610b3081610b1b565b82525050565b5f602082019050610b495f830184610b27565b92915050565b5f60208284031215610b6457610b636109a1565b5b5f610b71848285016109eb565b91505092915050565b5f5f60408385031215610b9057610b8f6109a1565b5b5f610b9d858286016109eb565b9250506020610bae858286016109eb565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610bfc57607f821691505b602082108103610c0f57610c0e610bb8565b5b50919050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f610c4960148361091b565b9150610c5482610c15565b602082019050919050565b5f6020820190508181035f830152610c7681610c3d565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f610cb160168361091b565b9150610cbc82610c7d565b602082019050919050565b5f6020820190508181035f830152610cde81610ca5565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610d1c826109ff565b9150610d27836109ff565b9250828203905081811115610d3f57610d3e610ce5565b5b92915050565b5f610d4f826109ff565b9150610d5a836109ff565b9250828201905080821115610d7257610d71610ce5565b5b9291505056fea26469706673582212207182ee741671c2a140c5eb4e62cb72b950c446fa68846143d961b62f544f59c764736f6c634300081e0033", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy10\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy11\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy12\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy13\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy14\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy15\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy16\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy17\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy18\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy19\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy2\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy20\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy21\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy22\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy23\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy24\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy25\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy26\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy27\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy28\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy29\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy3\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy30\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy31\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy32\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy33\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy34\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy35\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy36\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy37\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy38\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy39\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy4\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy40\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy41\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy42\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy43\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy44\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy45\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy46\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy47\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy48\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy49\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy5\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy50\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy51\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy52\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy53\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy54\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy55\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy56\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy57\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy58\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy59\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy6\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy60\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy61\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy62\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy63\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy64\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy65\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy66\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy67\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy68\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy69\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy7\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy70\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy71\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy72\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy73\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy74\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy75\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy8\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy9\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"salt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom1\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom10\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom11\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom12\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom13\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom14\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom15\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom16\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom17\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom18\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom19\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom3\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom4\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom5\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom6\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom7\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom8\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom9\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561000f575f5ffd5b50604051615fd4380380615fd4833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b60805161587f6107555f395f614a7b015261587f5ff3fe608060405234801561000f575f5ffd5b5060043610610606575f3560e01c8063657b6ef711610319578063b1802b9a116101a6578063d9bb3174116100f2578063f26c779b116100ab578063f8716f1411610085578063f8716f1414611360578063faf35ced1461137e578063fe7d5996146113ae578063ffbf0469146113cc57610606565b8063f26c779b14611306578063f4978b0414611324578063f5f573811461134257610606565b8063d9bb31741461122e578063dc1d8a9b1461124c578063dd62ed3e1461126a578063e2d275301461129a578063e8c927b3146112b8578063eb4329c8146112d657610606565b8063bbe231321161015f578063c958d4bf11610139578063c958d4bf146111b6578063cfd66863146111d4578063d101dcd0146111f2578063d74194691461121057610606565b8063bbe231321461114a578063bfa0b13314611168578063c2be97e31461118657610606565b8063b1802b9a14611072578063b2bb360e146110a2578063b4c48668146110c0578063b66dd750146110de578063b9a6d645146110fc578063bb9bfe061461111a57610606565b80637e544937116102655780639c5dfe731161021e578063a9059cbb116101f8578063a9059cbb14610fd6578063aaa7af7014611006578063acc5aee914611024578063ad8f42211461105457610606565b80639c5dfe7314610f7c5780639df61a2514610f9a578063a891d4d414610fb857610606565b80637e54493714610eb65780637f34d94b14610ed45780638619d60714610ef25780638789ca6714610f105780638f4a840614610f4057806395d89b4114610f5e57610606565b806374f83d02116102d25780637a319c18116102ac5780637a319c1814610e2c5780637c66673e14610e4a5780637c72ed0d14610e7a5780637dffdc3214610e9857610606565b806374f83d0214610dd257806377c0209e14610df0578063792c7f3e14610e0e57610606565b8063657b6ef714610ce8578063672151fe14610d185780636abceacd14610d365780636c12ed2814610d5457806370a0823114610d8457806374e73fd314610db457610606565b8063313ce567116104975780634b3c7f5f116103e357806358b6a9bd1161039c57806361b970eb1161037657806361b970eb14610c70578063639ec53a14610c8e5780636547317414610cac5780636578534c14610cca57610606565b806358b6a9bd14610c16578063595471b814610c345780635af92c0514610c5257610606565b80634b3c7f5f14610b3e5780634e1dbb8214610b5c5780634f5e555714610b7a5780634f7bd75a14610b9857806354c2792014610bc8578063552a1b5614610be657610606565b80633ea117ce1161045057806342937dbd1161042a57806342937dbd14610ab457806343a6b92d14610ad257806344050a2814610af05780634a2e93c614610b2057610606565b80633ea117ce14610a5a5780634128a85d14610a78578063418b181614610a9657610606565b8063313ce5671461098257806334517f0b146109a0578063378c5382146109be57806339e0bd12146109dc5780633a13199014610a0c5780633b6be45914610a3c57610606565b80631bbffe6f1161055657806321ecd7a31161050f5780632545d8b7116104e95780632545d8b7146108f85780632787325b14610916578063291c3bd7146109345780633125f37a1461096457610606565b806321ecd7a31461088c578063239af2a5146108aa57806323b872dd146108c857610606565b80631bbffe6f146107c65780631d527cde146107f65780631eaa7c52146108145780631f29783f146108325780631f449589146108505780631fd298ec1461086e57610606565b806312901b42116105c357806318160ddd1161059d57806318160ddd1461073c57806319cf6a911461075a5780631a97f18e146107785780631b17c65c1461079657610606565b806312901b42146106e257806313ebb5ec1461070057806316a3045b1461071e57610606565b80630460faf61461060a57806306fdde031461063a5780630717b16114610658578063095ea7b3146106765780630cb7a9e7146106a65780631215a3ab146106c4575b5f5ffd5b610624600480360381019061061f91906153a3565b6113ea565b604051610631919061540d565b60405180910390f35b6106426116ca565b60405161064f9190615496565b60405180910390f35b610660611755565b60405161066d91906154c5565b60405180910390f35b610690600480360381019061068b91906154de565b61175d565b60405161069d919061540d565b60405180910390f35b6106ae61184a565b6040516106bb91906154c5565b60405180910390f35b6106cc611852565b6040516106d991906154c5565b60405180910390f35b6106ea61185a565b6040516106f791906154c5565b60405180910390f35b610708611862565b60405161071591906154c5565b60405180910390f35b61072661186a565b60405161073391906154c5565b60405180910390f35b610744611872565b60405161075191906154c5565b60405180910390f35b610762611878565b60405161076f91906154c5565b60405180910390f35b610780611880565b60405161078d91906154c5565b60405180910390f35b6107b060048036038101906107ab91906153a3565b611888565b6040516107bd919061540d565b60405180910390f35b6107e060048036038101906107db91906153a3565b611b68565b6040516107ed919061540d565b60405180910390f35b6107fe611e48565b60405161080b91906154c5565b60405180910390f35b61081c611e50565b60405161082991906154c5565b60405180910390f35b61083a611e58565b60405161084791906154c5565b60405180910390f35b610858611e60565b60405161086591906154c5565b60405180910390f35b610876611e68565b60405161088391906154c5565b60405180910390f35b610894611e70565b6040516108a191906154c5565b60405180910390f35b6108b2611e78565b6040516108bf91906154c5565b60405180910390f35b6108e260048036038101906108dd91906153a3565b611e80565b6040516108ef919061540d565b60405180910390f35b610900612160565b60405161090d91906154c5565b60405180910390f35b61091e612168565b60405161092b91906154c5565b60405180910390f35b61094e600480360381019061094991906153a3565b612170565b60405161095b919061540d565b60405180910390f35b61096c612450565b60405161097991906154c5565b60405180910390f35b61098a612458565b6040516109979190615537565b60405180910390f35b6109a861246a565b6040516109b591906154c5565b60405180910390f35b6109c6612472565b6040516109d391906154c5565b60405180910390f35b6109f660048036038101906109f191906153a3565b61247a565b604051610a03919061540d565b60405180910390f35b610a266004803603810190610a2191906153a3565b61275a565b604051610a33919061540d565b60405180910390f35b610a44612a3a565b604051610a5191906154c5565b60405180910390f35b610a62612a42565b604051610a6f91906154c5565b60405180910390f35b610a80612a4a565b604051610a8d91906154c5565b60405180910390f35b610a9e612a52565b604051610aab91906154c5565b60405180910390f35b610abc612a5a565b604051610ac991906154c5565b60405180910390f35b610ada612a62565b604051610ae791906154c5565b60405180910390f35b610b0a6004803603810190610b0591906153a3565b612a6a565b604051610b17919061540d565b60405180910390f35b610b28612d4a565b604051610b3591906154c5565b60405180910390f35b610b46612d52565b604051610b5391906154c5565b60405180910390f35b610b64612d5a565b604051610b7191906154c5565b60405180910390f35b610b82612d62565b604051610b8f91906154c5565b60405180910390f35b610bb26004803603810190610bad91906153a3565b612d6a565b604051610bbf919061540d565b60405180910390f35b610bd061304a565b604051610bdd91906154c5565b60405180910390f35b610c006004803603810190610bfb91906153a3565b613052565b604051610c0d919061540d565b60405180910390f35b610c1e613332565b604051610c2b91906154c5565b60405180910390f35b610c3c61333a565b604051610c4991906154c5565b60405180910390f35b610c5a613342565b604051610c6791906154c5565b60405180910390f35b610c7861334a565b604051610c8591906154c5565b60405180910390f35b610c96613352565b604051610ca391906154c5565b60405180910390f35b610cb461335a565b604051610cc191906154c5565b60405180910390f35b610cd2613362565b604051610cdf91906154c5565b60405180910390f35b610d026004803603810190610cfd91906153a3565b61336a565b604051610d0f919061540d565b60405180910390f35b610d2061364a565b604051610d2d91906154c5565b60405180910390f35b610d3e613652565b604051610d4b91906154c5565b60405180910390f35b610d6e6004803603810190610d6991906153a3565b61365a565b604051610d7b919061540d565b60405180910390f35b610d9e6004803603810190610d999190615550565b61393a565b604051610dab91906154c5565b60405180910390f35b610dbc61394f565b604051610dc991906154c5565b60405180910390f35b610dda613957565b604051610de791906154c5565b60405180910390f35b610df861395f565b604051610e0591906154c5565b60405180910390f35b610e16613967565b604051610e2391906154c5565b60405180910390f35b610e3461396f565b604051610e4191906154c5565b60405180910390f35b610e646004803603810190610e5f91906153a3565b613977565b604051610e71919061540d565b60405180910390f35b610e82613c57565b604051610e8f91906154c5565b60405180910390f35b610ea0613c5f565b604051610ead91906154c5565b60405180910390f35b610ebe613c67565b604051610ecb91906154c5565b60405180910390f35b610edc613c6f565b604051610ee991906154c5565b60405180910390f35b610efa613c77565b604051610f0791906154c5565b60405180910390f35b610f2a6004803603810190610f2591906153a3565b613c7f565b604051610f37919061540d565b60405180910390f35b610f48613f5f565b604051610f5591906154c5565b60405180910390f35b610f66613f67565b604051610f739190615496565b60405180910390f35b610f84613ff3565b604051610f9191906154c5565b60405180910390f35b610fa2613ffb565b604051610faf91906154c5565b60405180910390f35b610fc0614003565b604051610fcd91906154c5565b60405180910390f35b610ff06004803603810190610feb91906154de565b61400b565b604051610ffd919061540d565b60405180910390f35b61100e6141a1565b60405161101b91906154c5565b60405180910390f35b61103e600480360381019061103991906153a3565b6141a9565b60405161104b919061540d565b60405180910390f35b61105c614489565b60405161106991906154c5565b60405180910390f35b61108c600480360381019061108791906153a3565b614491565b604051611099919061540d565b60405180910390f35b6110aa614771565b6040516110b791906154c5565b60405180910390f35b6110c8614779565b6040516110d591906154c5565b60405180910390f35b6110e6614781565b6040516110f391906154c5565b60405180910390f35b611104614789565b60405161111191906154c5565b60405180910390f35b611134600480360381019061112f91906153a3565b614791565b604051611141919061540d565b60405180910390f35b611152614a71565b60405161115f91906154c5565b60405180910390f35b611170614a79565b60405161117d91906154c5565b60405180910390f35b6111a0600480360381019061119b91906153a3565b614a9d565b6040516111ad919061540d565b60405180910390f35b6111be614d7d565b6040516111cb91906154c5565b60405180910390f35b6111dc614d85565b6040516111e991906154c5565b60405180910390f35b6111fa614d8d565b60405161120791906154c5565b60405180910390f35b611218614d95565b60405161122591906154c5565b60405180910390f35b611236614d9d565b60405161124391906154c5565b60405180910390f35b611254614da5565b60405161126191906154c5565b60405180910390f35b611284600480360381019061127f919061557b565b614dad565b60405161129191906154c5565b60405180910390f35b6112a2614dcd565b6040516112af91906154c5565b60405180910390f35b6112c0614dd5565b6040516112cd91906154c5565b60405180910390f35b6112f060048036038101906112eb91906153a3565b614ddd565b6040516112fd919061540d565b60405180910390f35b61130e615002565b60405161131b91906154c5565b60405180910390f35b61132c61500a565b60405161133991906154c5565b60405180910390f35b61134a615012565b60405161135791906154c5565b60405180910390f35b61136861501a565b60405161137591906154c5565b60405180910390f35b611398600480360381019061139391906153a3565b615022565b6040516113a5919061540d565b60405180910390f35b6113b6615302565b6040516113c391906154c5565b60405180910390f35b6113d461530a565b6040516113e191906154c5565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561146b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461157291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546115c591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461165391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516116b791906154c5565b60405180910390a3600190509392505050565b5f80546116d690615749565b80601f016020809104026020016040519081016040528092919081815260200182805461170290615749565b801561174d5780601f106117245761010080835404028352916020019161174d565b820191905f5260205f20905b81548152906001019060200180831161173057829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161183891906154c5565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190090615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156119c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bb9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611a1091906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611a6391906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611af191906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611b5591906154c5565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9b9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611cf091906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611d4391906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611dd191906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611e3591906154c5565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6048905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb39061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461200891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461205b91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546120e991906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161214d91906154c5565b60405180910390a3600190509392505050565b5f6001905090565b5f6045905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156121f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e8906157c3565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156122ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a39061582b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546122f891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461234b91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546123d991906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161243d91906154c5565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f604b905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156124fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156125b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ad9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461260291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461265591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546126e391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161274791906154c5565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156127db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546128e291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461293591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546129c391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612a2791906154c5565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612aeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ba6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612bf291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612c4591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612cd391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612d3791906154c5565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612de290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ea6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ef291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612f4591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612fd391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161303791906154c5565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156130d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ca90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561318e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131859061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546131da91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461322d91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546132bb91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161331f91906154c5565b60405180910390a3600190509392505050565b5f6009905090565b5f6049905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f6043905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156133eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133e2906157c3565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156134a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349d9061582b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546134f291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461354591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135d391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161363791906154c5565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156136db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136d290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161378d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546137e291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461383591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546138c391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161392791906154c5565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156139f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139ef90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613ab3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613aaa9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613aff91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613b5291906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613be091906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613c4491906154c5565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613d00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613cf790615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613db29061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e0791906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e5a91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ee891906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613f4c91906154c5565b60405180910390a3600190509392505050565b5f600b905090565b60018054613f7490615749565b80601f0160208091040260200160405190810160405280929190818152602001828054613fa090615749565b8015613feb5780601f10613fc257610100808354040283529160200191613feb565b820191905f5260205f20905b815481529060010190602001808311613fce57829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561408c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161408390615603565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546140d891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461412b91906156e9565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161418f91906154c5565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561422a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161422190615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156142e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016142dc9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461433191906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461438491906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461441291906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161447691906154c5565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161450990615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156145cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016145c49061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461461991906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461466c91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146fa91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161475e91906154c5565b60405180910390a3600190509392505050565b5f6018905090565b5f604a905090565b5f600f905090565b5f6044905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161480990615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156148cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148c49061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461491991906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461496c91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546149fa91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614a5e91906154c5565b60405180910390a3600190509392505050565b5f6046905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614b1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614b1590615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614bd09061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c2591906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c7891906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d0691906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614d6a91906154c5565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6042905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614e55906157c3565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614eaa91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614efd91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f8b91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614fef91906154c5565b60405180910390a3600190509392505050565b5f6007905090565b5f6047905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156150a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161509a90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561515e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016151559061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546151aa91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546151fd91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461528b91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516152ef91906154c5565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61533f82615316565b9050919050565b61534f81615335565b8114615359575f5ffd5b50565b5f8135905061536a81615346565b92915050565b5f819050919050565b61538281615370565b811461538c575f5ffd5b50565b5f8135905061539d81615379565b92915050565b5f5f5f606084860312156153ba576153b9615312565b5b5f6153c78682870161535c565b93505060206153d88682870161535c565b92505060406153e98682870161538f565b9150509250925092565b5f8115159050919050565b615407816153f3565b82525050565b5f6020820190506154205f8301846153fe565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61546882615426565b6154728185615430565b9350615482818560208601615440565b61548b8161544e565b840191505092915050565b5f6020820190508181035f8301526154ae818461545e565b905092915050565b6154bf81615370565b82525050565b5f6020820190506154d85f8301846154b6565b92915050565b5f5f604083850312156154f4576154f3615312565b5b5f6155018582860161535c565b92505060206155128582860161538f565b9150509250929050565b5f60ff82169050919050565b6155318161551c565b82525050565b5f60208201905061554a5f830184615528565b92915050565b5f6020828403121561556557615564615312565b5b5f6155728482850161535c565b91505092915050565b5f5f6040838503121561559157615590615312565b5b5f61559e8582860161535c565b92505060206155af8582860161535c565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6155ed601483615430565b91506155f8826155b9565b602082019050919050565b5f6020820190508181035f83015261561a816155e1565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f615655601683615430565b915061566082615621565b602082019050919050565b5f6020820190508181035f83015261568281615649565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6156c082615370565b91506156cb83615370565b92508282039050818111156156e3576156e2615689565b5b92915050565b5f6156f382615370565b91506156fe83615370565b925082820190508082111561571657615715615689565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061576057607f821691505b6020821081036157735761577261571c565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6157ad600183615430565b91506157b882615779565b602082019050919050565b5f6020820190508181035f8301526157da816157a1565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f615815600183615430565b9150615820826157e1565b602082019050919050565b5f6020820190508181035f83015261584281615809565b905091905056fea2646970667358221220ce03f2ea0f8ec341a07b9c0512b41f44d879b740c55b3572c5707216663e8a3f64736f6c634300081e0033", } // ContractABI is the input ABI used to generate the binding from. @@ -295,6 +295,2331 @@ func (_Contract *ContractCallerSession) Decimals() (uint8, error) { return _Contract.Contract.Decimals(&_Contract.CallOpts) } +// Dummy1 is a free data retrieval call binding the contract method 0x2545d8b7. +// +// Solidity: function dummy1() pure returns(uint256) +func (_Contract *ContractCaller) Dummy1(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy1") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy1 is a free data retrieval call binding the contract method 0x2545d8b7. +// +// Solidity: function dummy1() pure returns(uint256) +func (_Contract *ContractSession) Dummy1() (*big.Int, error) { + return _Contract.Contract.Dummy1(&_Contract.CallOpts) +} + +// Dummy1 is a free data retrieval call binding the contract method 0x2545d8b7. +// +// Solidity: function dummy1() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy1() (*big.Int, error) { + return _Contract.Contract.Dummy1(&_Contract.CallOpts) +} + +// Dummy10 is a free data retrieval call binding the contract method 0x7e544937. +// +// Solidity: function dummy10() pure returns(uint256) +func (_Contract *ContractCaller) Dummy10(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy10") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy10 is a free data retrieval call binding the contract method 0x7e544937. +// +// Solidity: function dummy10() pure returns(uint256) +func (_Contract *ContractSession) Dummy10() (*big.Int, error) { + return _Contract.Contract.Dummy10(&_Contract.CallOpts) +} + +// Dummy10 is a free data retrieval call binding the contract method 0x7e544937. +// +// Solidity: function dummy10() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy10() (*big.Int, error) { + return _Contract.Contract.Dummy10(&_Contract.CallOpts) +} + +// Dummy11 is a free data retrieval call binding the contract method 0x8f4a8406. +// +// Solidity: function dummy11() pure returns(uint256) +func (_Contract *ContractCaller) Dummy11(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy11") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy11 is a free data retrieval call binding the contract method 0x8f4a8406. +// +// Solidity: function dummy11() pure returns(uint256) +func (_Contract *ContractSession) Dummy11() (*big.Int, error) { + return _Contract.Contract.Dummy11(&_Contract.CallOpts) +} + +// Dummy11 is a free data retrieval call binding the contract method 0x8f4a8406. +// +// Solidity: function dummy11() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy11() (*big.Int, error) { + return _Contract.Contract.Dummy11(&_Contract.CallOpts) +} + +// Dummy12 is a free data retrieval call binding the contract method 0x3ea117ce. +// +// Solidity: function dummy12() pure returns(uint256) +func (_Contract *ContractCaller) Dummy12(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy12") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy12 is a free data retrieval call binding the contract method 0x3ea117ce. +// +// Solidity: function dummy12() pure returns(uint256) +func (_Contract *ContractSession) Dummy12() (*big.Int, error) { + return _Contract.Contract.Dummy12(&_Contract.CallOpts) +} + +// Dummy12 is a free data retrieval call binding the contract method 0x3ea117ce. +// +// Solidity: function dummy12() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy12() (*big.Int, error) { + return _Contract.Contract.Dummy12(&_Contract.CallOpts) +} + +// Dummy13 is a free data retrieval call binding the contract method 0x672151fe. +// +// Solidity: function dummy13() pure returns(uint256) +func (_Contract *ContractCaller) Dummy13(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy13") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy13 is a free data retrieval call binding the contract method 0x672151fe. +// +// Solidity: function dummy13() pure returns(uint256) +func (_Contract *ContractSession) Dummy13() (*big.Int, error) { + return _Contract.Contract.Dummy13(&_Contract.CallOpts) +} + +// Dummy13 is a free data retrieval call binding the contract method 0x672151fe. +// +// Solidity: function dummy13() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy13() (*big.Int, error) { + return _Contract.Contract.Dummy13(&_Contract.CallOpts) +} + +// Dummy14 is a free data retrieval call binding the contract method 0xfe7d5996. +// +// Solidity: function dummy14() pure returns(uint256) +func (_Contract *ContractCaller) Dummy14(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy14") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy14 is a free data retrieval call binding the contract method 0xfe7d5996. +// +// Solidity: function dummy14() pure returns(uint256) +func (_Contract *ContractSession) Dummy14() (*big.Int, error) { + return _Contract.Contract.Dummy14(&_Contract.CallOpts) +} + +// Dummy14 is a free data retrieval call binding the contract method 0xfe7d5996. +// +// Solidity: function dummy14() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy14() (*big.Int, error) { + return _Contract.Contract.Dummy14(&_Contract.CallOpts) +} + +// Dummy15 is a free data retrieval call binding the contract method 0xb66dd750. +// +// Solidity: function dummy15() pure returns(uint256) +func (_Contract *ContractCaller) Dummy15(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy15") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy15 is a free data retrieval call binding the contract method 0xb66dd750. +// +// Solidity: function dummy15() pure returns(uint256) +func (_Contract *ContractSession) Dummy15() (*big.Int, error) { + return _Contract.Contract.Dummy15(&_Contract.CallOpts) +} + +// Dummy15 is a free data retrieval call binding the contract method 0xb66dd750. +// +// Solidity: function dummy15() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy15() (*big.Int, error) { + return _Contract.Contract.Dummy15(&_Contract.CallOpts) +} + +// Dummy16 is a free data retrieval call binding the contract method 0x1eaa7c52. +// +// Solidity: function dummy16() pure returns(uint256) +func (_Contract *ContractCaller) Dummy16(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy16") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy16 is a free data retrieval call binding the contract method 0x1eaa7c52. +// +// Solidity: function dummy16() pure returns(uint256) +func (_Contract *ContractSession) Dummy16() (*big.Int, error) { + return _Contract.Contract.Dummy16(&_Contract.CallOpts) +} + +// Dummy16 is a free data retrieval call binding the contract method 0x1eaa7c52. +// +// Solidity: function dummy16() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy16() (*big.Int, error) { + return _Contract.Contract.Dummy16(&_Contract.CallOpts) +} + +// Dummy17 is a free data retrieval call binding the contract method 0x4a2e93c6. +// +// Solidity: function dummy17() pure returns(uint256) +func (_Contract *ContractCaller) Dummy17(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy17") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy17 is a free data retrieval call binding the contract method 0x4a2e93c6. +// +// Solidity: function dummy17() pure returns(uint256) +func (_Contract *ContractSession) Dummy17() (*big.Int, error) { + return _Contract.Contract.Dummy17(&_Contract.CallOpts) +} + +// Dummy17 is a free data retrieval call binding the contract method 0x4a2e93c6. +// +// Solidity: function dummy17() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy17() (*big.Int, error) { + return _Contract.Contract.Dummy17(&_Contract.CallOpts) +} + +// Dummy18 is a free data retrieval call binding the contract method 0xffbf0469. +// +// Solidity: function dummy18() pure returns(uint256) +func (_Contract *ContractCaller) Dummy18(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy18") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy18 is a free data retrieval call binding the contract method 0xffbf0469. +// +// Solidity: function dummy18() pure returns(uint256) +func (_Contract *ContractSession) Dummy18() (*big.Int, error) { + return _Contract.Contract.Dummy18(&_Contract.CallOpts) +} + +// Dummy18 is a free data retrieval call binding the contract method 0xffbf0469. +// +// Solidity: function dummy18() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy18() (*big.Int, error) { + return _Contract.Contract.Dummy18(&_Contract.CallOpts) +} + +// Dummy19 is a free data retrieval call binding the contract method 0x65473174. +// +// Solidity: function dummy19() pure returns(uint256) +func (_Contract *ContractCaller) Dummy19(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy19") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy19 is a free data retrieval call binding the contract method 0x65473174. +// +// Solidity: function dummy19() pure returns(uint256) +func (_Contract *ContractSession) Dummy19() (*big.Int, error) { + return _Contract.Contract.Dummy19(&_Contract.CallOpts) +} + +// Dummy19 is a free data retrieval call binding the contract method 0x65473174. +// +// Solidity: function dummy19() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy19() (*big.Int, error) { + return _Contract.Contract.Dummy19(&_Contract.CallOpts) +} + +// Dummy2 is a free data retrieval call binding the contract method 0x1d527cde. +// +// Solidity: function dummy2() pure returns(uint256) +func (_Contract *ContractCaller) Dummy2(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy2") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy2 is a free data retrieval call binding the contract method 0x1d527cde. +// +// Solidity: function dummy2() pure returns(uint256) +func (_Contract *ContractSession) Dummy2() (*big.Int, error) { + return _Contract.Contract.Dummy2(&_Contract.CallOpts) +} + +// Dummy2 is a free data retrieval call binding the contract method 0x1d527cde. +// +// Solidity: function dummy2() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy2() (*big.Int, error) { + return _Contract.Contract.Dummy2(&_Contract.CallOpts) +} + +// Dummy20 is a free data retrieval call binding the contract method 0x61b970eb. +// +// Solidity: function dummy20() pure returns(uint256) +func (_Contract *ContractCaller) Dummy20(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy20") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy20 is a free data retrieval call binding the contract method 0x61b970eb. +// +// Solidity: function dummy20() pure returns(uint256) +func (_Contract *ContractSession) Dummy20() (*big.Int, error) { + return _Contract.Contract.Dummy20(&_Contract.CallOpts) +} + +// Dummy20 is a free data retrieval call binding the contract method 0x61b970eb. +// +// Solidity: function dummy20() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy20() (*big.Int, error) { + return _Contract.Contract.Dummy20(&_Contract.CallOpts) +} + +// Dummy21 is a free data retrieval call binding the contract method 0x9c5dfe73. +// +// Solidity: function dummy21() pure returns(uint256) +func (_Contract *ContractCaller) Dummy21(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy21") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy21 is a free data retrieval call binding the contract method 0x9c5dfe73. +// +// Solidity: function dummy21() pure returns(uint256) +func (_Contract *ContractSession) Dummy21() (*big.Int, error) { + return _Contract.Contract.Dummy21(&_Contract.CallOpts) +} + +// Dummy21 is a free data retrieval call binding the contract method 0x9c5dfe73. +// +// Solidity: function dummy21() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy21() (*big.Int, error) { + return _Contract.Contract.Dummy21(&_Contract.CallOpts) +} + +// Dummy22 is a free data retrieval call binding the contract method 0x74e73fd3. +// +// Solidity: function dummy22() pure returns(uint256) +func (_Contract *ContractCaller) Dummy22(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy22") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy22 is a free data retrieval call binding the contract method 0x74e73fd3. +// +// Solidity: function dummy22() pure returns(uint256) +func (_Contract *ContractSession) Dummy22() (*big.Int, error) { + return _Contract.Contract.Dummy22(&_Contract.CallOpts) +} + +// Dummy22 is a free data retrieval call binding the contract method 0x74e73fd3. +// +// Solidity: function dummy22() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy22() (*big.Int, error) { + return _Contract.Contract.Dummy22(&_Contract.CallOpts) +} + +// Dummy23 is a free data retrieval call binding the contract method 0x6abceacd. +// +// Solidity: function dummy23() pure returns(uint256) +func (_Contract *ContractCaller) Dummy23(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy23") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy23 is a free data retrieval call binding the contract method 0x6abceacd. +// +// Solidity: function dummy23() pure returns(uint256) +func (_Contract *ContractSession) Dummy23() (*big.Int, error) { + return _Contract.Contract.Dummy23(&_Contract.CallOpts) +} + +// Dummy23 is a free data retrieval call binding the contract method 0x6abceacd. +// +// Solidity: function dummy23() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy23() (*big.Int, error) { + return _Contract.Contract.Dummy23(&_Contract.CallOpts) +} + +// Dummy24 is a free data retrieval call binding the contract method 0xb2bb360e. +// +// Solidity: function dummy24() pure returns(uint256) +func (_Contract *ContractCaller) Dummy24(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy24") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy24 is a free data retrieval call binding the contract method 0xb2bb360e. +// +// Solidity: function dummy24() pure returns(uint256) +func (_Contract *ContractSession) Dummy24() (*big.Int, error) { + return _Contract.Contract.Dummy24(&_Contract.CallOpts) +} + +// Dummy24 is a free data retrieval call binding the contract method 0xb2bb360e. +// +// Solidity: function dummy24() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy24() (*big.Int, error) { + return _Contract.Contract.Dummy24(&_Contract.CallOpts) +} + +// Dummy25 is a free data retrieval call binding the contract method 0xd7419469. +// +// Solidity: function dummy25() pure returns(uint256) +func (_Contract *ContractCaller) Dummy25(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy25") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy25 is a free data retrieval call binding the contract method 0xd7419469. +// +// Solidity: function dummy25() pure returns(uint256) +func (_Contract *ContractSession) Dummy25() (*big.Int, error) { + return _Contract.Contract.Dummy25(&_Contract.CallOpts) +} + +// Dummy25 is a free data retrieval call binding the contract method 0xd7419469. +// +// Solidity: function dummy25() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy25() (*big.Int, error) { + return _Contract.Contract.Dummy25(&_Contract.CallOpts) +} + +// Dummy26 is a free data retrieval call binding the contract method 0x12901b42. +// +// Solidity: function dummy26() pure returns(uint256) +func (_Contract *ContractCaller) Dummy26(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy26") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy26 is a free data retrieval call binding the contract method 0x12901b42. +// +// Solidity: function dummy26() pure returns(uint256) +func (_Contract *ContractSession) Dummy26() (*big.Int, error) { + return _Contract.Contract.Dummy26(&_Contract.CallOpts) +} + +// Dummy26 is a free data retrieval call binding the contract method 0x12901b42. +// +// Solidity: function dummy26() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy26() (*big.Int, error) { + return _Contract.Contract.Dummy26(&_Contract.CallOpts) +} + +// Dummy27 is a free data retrieval call binding the contract method 0x0cb7a9e7. +// +// Solidity: function dummy27() pure returns(uint256) +func (_Contract *ContractCaller) Dummy27(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy27") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy27 is a free data retrieval call binding the contract method 0x0cb7a9e7. +// +// Solidity: function dummy27() pure returns(uint256) +func (_Contract *ContractSession) Dummy27() (*big.Int, error) { + return _Contract.Contract.Dummy27(&_Contract.CallOpts) +} + +// Dummy27 is a free data retrieval call binding the contract method 0x0cb7a9e7. +// +// Solidity: function dummy27() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy27() (*big.Int, error) { + return _Contract.Contract.Dummy27(&_Contract.CallOpts) +} + +// Dummy28 is a free data retrieval call binding the contract method 0x418b1816. +// +// Solidity: function dummy28() pure returns(uint256) +func (_Contract *ContractCaller) Dummy28(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy28") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy28 is a free data retrieval call binding the contract method 0x418b1816. +// +// Solidity: function dummy28() pure returns(uint256) +func (_Contract *ContractSession) Dummy28() (*big.Int, error) { + return _Contract.Contract.Dummy28(&_Contract.CallOpts) +} + +// Dummy28 is a free data retrieval call binding the contract method 0x418b1816. +// +// Solidity: function dummy28() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy28() (*big.Int, error) { + return _Contract.Contract.Dummy28(&_Contract.CallOpts) +} + +// Dummy29 is a free data retrieval call binding the contract method 0x13ebb5ec. +// +// Solidity: function dummy29() pure returns(uint256) +func (_Contract *ContractCaller) Dummy29(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy29") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy29 is a free data retrieval call binding the contract method 0x13ebb5ec. +// +// Solidity: function dummy29() pure returns(uint256) +func (_Contract *ContractSession) Dummy29() (*big.Int, error) { + return _Contract.Contract.Dummy29(&_Contract.CallOpts) +} + +// Dummy29 is a free data retrieval call binding the contract method 0x13ebb5ec. +// +// Solidity: function dummy29() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy29() (*big.Int, error) { + return _Contract.Contract.Dummy29(&_Contract.CallOpts) +} + +// Dummy3 is a free data retrieval call binding the contract method 0x1a97f18e. +// +// Solidity: function dummy3() pure returns(uint256) +func (_Contract *ContractCaller) Dummy3(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy3") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy3 is a free data retrieval call binding the contract method 0x1a97f18e. +// +// Solidity: function dummy3() pure returns(uint256) +func (_Contract *ContractSession) Dummy3() (*big.Int, error) { + return _Contract.Contract.Dummy3(&_Contract.CallOpts) +} + +// Dummy3 is a free data retrieval call binding the contract method 0x1a97f18e. +// +// Solidity: function dummy3() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy3() (*big.Int, error) { + return _Contract.Contract.Dummy3(&_Contract.CallOpts) +} + +// Dummy30 is a free data retrieval call binding the contract method 0xcfd66863. +// +// Solidity: function dummy30() pure returns(uint256) +func (_Contract *ContractCaller) Dummy30(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy30") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy30 is a free data retrieval call binding the contract method 0xcfd66863. +// +// Solidity: function dummy30() pure returns(uint256) +func (_Contract *ContractSession) Dummy30() (*big.Int, error) { + return _Contract.Contract.Dummy30(&_Contract.CallOpts) +} + +// Dummy30 is a free data retrieval call binding the contract method 0xcfd66863. +// +// Solidity: function dummy30() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy30() (*big.Int, error) { + return _Contract.Contract.Dummy30(&_Contract.CallOpts) +} + +// Dummy31 is a free data retrieval call binding the contract method 0x4e1dbb82. +// +// Solidity: function dummy31() pure returns(uint256) +func (_Contract *ContractCaller) Dummy31(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy31") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy31 is a free data retrieval call binding the contract method 0x4e1dbb82. +// +// Solidity: function dummy31() pure returns(uint256) +func (_Contract *ContractSession) Dummy31() (*big.Int, error) { + return _Contract.Contract.Dummy31(&_Contract.CallOpts) +} + +// Dummy31 is a free data retrieval call binding the contract method 0x4e1dbb82. +// +// Solidity: function dummy31() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy31() (*big.Int, error) { + return _Contract.Contract.Dummy31(&_Contract.CallOpts) +} + +// Dummy32 is a free data retrieval call binding the contract method 0xf8716f14. +// +// Solidity: function dummy32() pure returns(uint256) +func (_Contract *ContractCaller) Dummy32(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy32") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy32 is a free data retrieval call binding the contract method 0xf8716f14. +// +// Solidity: function dummy32() pure returns(uint256) +func (_Contract *ContractSession) Dummy32() (*big.Int, error) { + return _Contract.Contract.Dummy32(&_Contract.CallOpts) +} + +// Dummy32 is a free data retrieval call binding the contract method 0xf8716f14. +// +// Solidity: function dummy32() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy32() (*big.Int, error) { + return _Contract.Contract.Dummy32(&_Contract.CallOpts) +} + +// Dummy33 is a free data retrieval call binding the contract method 0x4b3c7f5f. +// +// Solidity: function dummy33() pure returns(uint256) +func (_Contract *ContractCaller) Dummy33(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy33") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy33 is a free data retrieval call binding the contract method 0x4b3c7f5f. +// +// Solidity: function dummy33() pure returns(uint256) +func (_Contract *ContractSession) Dummy33() (*big.Int, error) { + return _Contract.Contract.Dummy33(&_Contract.CallOpts) +} + +// Dummy33 is a free data retrieval call binding the contract method 0x4b3c7f5f. +// +// Solidity: function dummy33() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy33() (*big.Int, error) { + return _Contract.Contract.Dummy33(&_Contract.CallOpts) +} + +// Dummy34 is a free data retrieval call binding the contract method 0xe8c927b3. +// +// Solidity: function dummy34() pure returns(uint256) +func (_Contract *ContractCaller) Dummy34(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy34") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy34 is a free data retrieval call binding the contract method 0xe8c927b3. +// +// Solidity: function dummy34() pure returns(uint256) +func (_Contract *ContractSession) Dummy34() (*big.Int, error) { + return _Contract.Contract.Dummy34(&_Contract.CallOpts) +} + +// Dummy34 is a free data retrieval call binding the contract method 0xe8c927b3. +// +// Solidity: function dummy34() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy34() (*big.Int, error) { + return _Contract.Contract.Dummy34(&_Contract.CallOpts) +} + +// Dummy35 is a free data retrieval call binding the contract method 0x43a6b92d. +// +// Solidity: function dummy35() pure returns(uint256) +func (_Contract *ContractCaller) Dummy35(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy35") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy35 is a free data retrieval call binding the contract method 0x43a6b92d. +// +// Solidity: function dummy35() pure returns(uint256) +func (_Contract *ContractSession) Dummy35() (*big.Int, error) { + return _Contract.Contract.Dummy35(&_Contract.CallOpts) +} + +// Dummy35 is a free data retrieval call binding the contract method 0x43a6b92d. +// +// Solidity: function dummy35() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy35() (*big.Int, error) { + return _Contract.Contract.Dummy35(&_Contract.CallOpts) +} + +// Dummy36 is a free data retrieval call binding the contract method 0xc958d4bf. +// +// Solidity: function dummy36() pure returns(uint256) +func (_Contract *ContractCaller) Dummy36(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy36") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy36 is a free data retrieval call binding the contract method 0xc958d4bf. +// +// Solidity: function dummy36() pure returns(uint256) +func (_Contract *ContractSession) Dummy36() (*big.Int, error) { + return _Contract.Contract.Dummy36(&_Contract.CallOpts) +} + +// Dummy36 is a free data retrieval call binding the contract method 0xc958d4bf. +// +// Solidity: function dummy36() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy36() (*big.Int, error) { + return _Contract.Contract.Dummy36(&_Contract.CallOpts) +} + +// Dummy37 is a free data retrieval call binding the contract method 0x639ec53a. +// +// Solidity: function dummy37() pure returns(uint256) +func (_Contract *ContractCaller) Dummy37(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy37") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy37 is a free data retrieval call binding the contract method 0x639ec53a. +// +// Solidity: function dummy37() pure returns(uint256) +func (_Contract *ContractSession) Dummy37() (*big.Int, error) { + return _Contract.Contract.Dummy37(&_Contract.CallOpts) +} + +// Dummy37 is a free data retrieval call binding the contract method 0x639ec53a. +// +// Solidity: function dummy37() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy37() (*big.Int, error) { + return _Contract.Contract.Dummy37(&_Contract.CallOpts) +} + +// Dummy38 is a free data retrieval call binding the contract method 0x4f5e5557. +// +// Solidity: function dummy38() pure returns(uint256) +func (_Contract *ContractCaller) Dummy38(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy38") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy38 is a free data retrieval call binding the contract method 0x4f5e5557. +// +// Solidity: function dummy38() pure returns(uint256) +func (_Contract *ContractSession) Dummy38() (*big.Int, error) { + return _Contract.Contract.Dummy38(&_Contract.CallOpts) +} + +// Dummy38 is a free data retrieval call binding the contract method 0x4f5e5557. +// +// Solidity: function dummy38() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy38() (*big.Int, error) { + return _Contract.Contract.Dummy38(&_Contract.CallOpts) +} + +// Dummy39 is a free data retrieval call binding the contract method 0xdc1d8a9b. +// +// Solidity: function dummy39() pure returns(uint256) +func (_Contract *ContractCaller) Dummy39(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy39") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy39 is a free data retrieval call binding the contract method 0xdc1d8a9b. +// +// Solidity: function dummy39() pure returns(uint256) +func (_Contract *ContractSession) Dummy39() (*big.Int, error) { + return _Contract.Contract.Dummy39(&_Contract.CallOpts) +} + +// Dummy39 is a free data retrieval call binding the contract method 0xdc1d8a9b. +// +// Solidity: function dummy39() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy39() (*big.Int, error) { + return _Contract.Contract.Dummy39(&_Contract.CallOpts) +} + +// Dummy4 is a free data retrieval call binding the contract method 0x3b6be459. +// +// Solidity: function dummy4() pure returns(uint256) +func (_Contract *ContractCaller) Dummy4(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy4") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy4 is a free data retrieval call binding the contract method 0x3b6be459. +// +// Solidity: function dummy4() pure returns(uint256) +func (_Contract *ContractSession) Dummy4() (*big.Int, error) { + return _Contract.Contract.Dummy4(&_Contract.CallOpts) +} + +// Dummy4 is a free data retrieval call binding the contract method 0x3b6be459. +// +// Solidity: function dummy4() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy4() (*big.Int, error) { + return _Contract.Contract.Dummy4(&_Contract.CallOpts) +} + +// Dummy40 is a free data retrieval call binding the contract method 0xaaa7af70. +// +// Solidity: function dummy40() pure returns(uint256) +func (_Contract *ContractCaller) Dummy40(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy40") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy40 is a free data retrieval call binding the contract method 0xaaa7af70. +// +// Solidity: function dummy40() pure returns(uint256) +func (_Contract *ContractSession) Dummy40() (*big.Int, error) { + return _Contract.Contract.Dummy40(&_Contract.CallOpts) +} + +// Dummy40 is a free data retrieval call binding the contract method 0xaaa7af70. +// +// Solidity: function dummy40() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy40() (*big.Int, error) { + return _Contract.Contract.Dummy40(&_Contract.CallOpts) +} + +// Dummy41 is a free data retrieval call binding the contract method 0x9df61a25. +// +// Solidity: function dummy41() pure returns(uint256) +func (_Contract *ContractCaller) Dummy41(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy41") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy41 is a free data retrieval call binding the contract method 0x9df61a25. +// +// Solidity: function dummy41() pure returns(uint256) +func (_Contract *ContractSession) Dummy41() (*big.Int, error) { + return _Contract.Contract.Dummy41(&_Contract.CallOpts) +} + +// Dummy41 is a free data retrieval call binding the contract method 0x9df61a25. +// +// Solidity: function dummy41() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy41() (*big.Int, error) { + return _Contract.Contract.Dummy41(&_Contract.CallOpts) +} + +// Dummy42 is a free data retrieval call binding the contract method 0x5af92c05. +// +// Solidity: function dummy42() pure returns(uint256) +func (_Contract *ContractCaller) Dummy42(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy42") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy42 is a free data retrieval call binding the contract method 0x5af92c05. +// +// Solidity: function dummy42() pure returns(uint256) +func (_Contract *ContractSession) Dummy42() (*big.Int, error) { + return _Contract.Contract.Dummy42(&_Contract.CallOpts) +} + +// Dummy42 is a free data retrieval call binding the contract method 0x5af92c05. +// +// Solidity: function dummy42() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy42() (*big.Int, error) { + return _Contract.Contract.Dummy42(&_Contract.CallOpts) +} + +// Dummy43 is a free data retrieval call binding the contract method 0x7c72ed0d. +// +// Solidity: function dummy43() pure returns(uint256) +func (_Contract *ContractCaller) Dummy43(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy43") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy43 is a free data retrieval call binding the contract method 0x7c72ed0d. +// +// Solidity: function dummy43() pure returns(uint256) +func (_Contract *ContractSession) Dummy43() (*big.Int, error) { + return _Contract.Contract.Dummy43(&_Contract.CallOpts) +} + +// Dummy43 is a free data retrieval call binding the contract method 0x7c72ed0d. +// +// Solidity: function dummy43() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy43() (*big.Int, error) { + return _Contract.Contract.Dummy43(&_Contract.CallOpts) +} + +// Dummy44 is a free data retrieval call binding the contract method 0x239af2a5. +// +// Solidity: function dummy44() pure returns(uint256) +func (_Contract *ContractCaller) Dummy44(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy44") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy44 is a free data retrieval call binding the contract method 0x239af2a5. +// +// Solidity: function dummy44() pure returns(uint256) +func (_Contract *ContractSession) Dummy44() (*big.Int, error) { + return _Contract.Contract.Dummy44(&_Contract.CallOpts) +} + +// Dummy44 is a free data retrieval call binding the contract method 0x239af2a5. +// +// Solidity: function dummy44() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy44() (*big.Int, error) { + return _Contract.Contract.Dummy44(&_Contract.CallOpts) +} + +// Dummy45 is a free data retrieval call binding the contract method 0x7f34d94b. +// +// Solidity: function dummy45() pure returns(uint256) +func (_Contract *ContractCaller) Dummy45(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy45") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy45 is a free data retrieval call binding the contract method 0x7f34d94b. +// +// Solidity: function dummy45() pure returns(uint256) +func (_Contract *ContractSession) Dummy45() (*big.Int, error) { + return _Contract.Contract.Dummy45(&_Contract.CallOpts) +} + +// Dummy45 is a free data retrieval call binding the contract method 0x7f34d94b. +// +// Solidity: function dummy45() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy45() (*big.Int, error) { + return _Contract.Contract.Dummy45(&_Contract.CallOpts) +} + +// Dummy46 is a free data retrieval call binding the contract method 0x21ecd7a3. +// +// Solidity: function dummy46() pure returns(uint256) +func (_Contract *ContractCaller) Dummy46(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy46") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy46 is a free data retrieval call binding the contract method 0x21ecd7a3. +// +// Solidity: function dummy46() pure returns(uint256) +func (_Contract *ContractSession) Dummy46() (*big.Int, error) { + return _Contract.Contract.Dummy46(&_Contract.CallOpts) +} + +// Dummy46 is a free data retrieval call binding the contract method 0x21ecd7a3. +// +// Solidity: function dummy46() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy46() (*big.Int, error) { + return _Contract.Contract.Dummy46(&_Contract.CallOpts) +} + +// Dummy47 is a free data retrieval call binding the contract method 0x0717b161. +// +// Solidity: function dummy47() pure returns(uint256) +func (_Contract *ContractCaller) Dummy47(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy47") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy47 is a free data retrieval call binding the contract method 0x0717b161. +// +// Solidity: function dummy47() pure returns(uint256) +func (_Contract *ContractSession) Dummy47() (*big.Int, error) { + return _Contract.Contract.Dummy47(&_Contract.CallOpts) +} + +// Dummy47 is a free data retrieval call binding the contract method 0x0717b161. +// +// Solidity: function dummy47() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy47() (*big.Int, error) { + return _Contract.Contract.Dummy47(&_Contract.CallOpts) +} + +// Dummy48 is a free data retrieval call binding the contract method 0x8619d607. +// +// Solidity: function dummy48() pure returns(uint256) +func (_Contract *ContractCaller) Dummy48(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy48") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy48 is a free data retrieval call binding the contract method 0x8619d607. +// +// Solidity: function dummy48() pure returns(uint256) +func (_Contract *ContractSession) Dummy48() (*big.Int, error) { + return _Contract.Contract.Dummy48(&_Contract.CallOpts) +} + +// Dummy48 is a free data retrieval call binding the contract method 0x8619d607. +// +// Solidity: function dummy48() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy48() (*big.Int, error) { + return _Contract.Contract.Dummy48(&_Contract.CallOpts) +} + +// Dummy49 is a free data retrieval call binding the contract method 0xd101dcd0. +// +// Solidity: function dummy49() pure returns(uint256) +func (_Contract *ContractCaller) Dummy49(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy49") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy49 is a free data retrieval call binding the contract method 0xd101dcd0. +// +// Solidity: function dummy49() pure returns(uint256) +func (_Contract *ContractSession) Dummy49() (*big.Int, error) { + return _Contract.Contract.Dummy49(&_Contract.CallOpts) +} + +// Dummy49 is a free data retrieval call binding the contract method 0xd101dcd0. +// +// Solidity: function dummy49() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy49() (*big.Int, error) { + return _Contract.Contract.Dummy49(&_Contract.CallOpts) +} + +// Dummy5 is a free data retrieval call binding the contract method 0x1215a3ab. +// +// Solidity: function dummy5() pure returns(uint256) +func (_Contract *ContractCaller) Dummy5(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy5") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy5 is a free data retrieval call binding the contract method 0x1215a3ab. +// +// Solidity: function dummy5() pure returns(uint256) +func (_Contract *ContractSession) Dummy5() (*big.Int, error) { + return _Contract.Contract.Dummy5(&_Contract.CallOpts) +} + +// Dummy5 is a free data retrieval call binding the contract method 0x1215a3ab. +// +// Solidity: function dummy5() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy5() (*big.Int, error) { + return _Contract.Contract.Dummy5(&_Contract.CallOpts) +} + +// Dummy50 is a free data retrieval call binding the contract method 0x42937dbd. +// +// Solidity: function dummy50() pure returns(uint256) +func (_Contract *ContractCaller) Dummy50(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy50") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy50 is a free data retrieval call binding the contract method 0x42937dbd. +// +// Solidity: function dummy50() pure returns(uint256) +func (_Contract *ContractSession) Dummy50() (*big.Int, error) { + return _Contract.Contract.Dummy50(&_Contract.CallOpts) +} + +// Dummy50 is a free data retrieval call binding the contract method 0x42937dbd. +// +// Solidity: function dummy50() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy50() (*big.Int, error) { + return _Contract.Contract.Dummy50(&_Contract.CallOpts) +} + +// Dummy51 is a free data retrieval call binding the contract method 0x16a3045b. +// +// Solidity: function dummy51() pure returns(uint256) +func (_Contract *ContractCaller) Dummy51(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy51") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy51 is a free data retrieval call binding the contract method 0x16a3045b. +// +// Solidity: function dummy51() pure returns(uint256) +func (_Contract *ContractSession) Dummy51() (*big.Int, error) { + return _Contract.Contract.Dummy51(&_Contract.CallOpts) +} + +// Dummy51 is a free data retrieval call binding the contract method 0x16a3045b. +// +// Solidity: function dummy51() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy51() (*big.Int, error) { + return _Contract.Contract.Dummy51(&_Contract.CallOpts) +} + +// Dummy52 is a free data retrieval call binding the contract method 0x3125f37a. +// +// Solidity: function dummy52() pure returns(uint256) +func (_Contract *ContractCaller) Dummy52(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy52") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy52 is a free data retrieval call binding the contract method 0x3125f37a. +// +// Solidity: function dummy52() pure returns(uint256) +func (_Contract *ContractSession) Dummy52() (*big.Int, error) { + return _Contract.Contract.Dummy52(&_Contract.CallOpts) +} + +// Dummy52 is a free data retrieval call binding the contract method 0x3125f37a. +// +// Solidity: function dummy52() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy52() (*big.Int, error) { + return _Contract.Contract.Dummy52(&_Contract.CallOpts) +} + +// Dummy53 is a free data retrieval call binding the contract method 0x1fd298ec. +// +// Solidity: function dummy53() pure returns(uint256) +func (_Contract *ContractCaller) Dummy53(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy53") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy53 is a free data retrieval call binding the contract method 0x1fd298ec. +// +// Solidity: function dummy53() pure returns(uint256) +func (_Contract *ContractSession) Dummy53() (*big.Int, error) { + return _Contract.Contract.Dummy53(&_Contract.CallOpts) +} + +// Dummy53 is a free data retrieval call binding the contract method 0x1fd298ec. +// +// Solidity: function dummy53() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy53() (*big.Int, error) { + return _Contract.Contract.Dummy53(&_Contract.CallOpts) +} + +// Dummy54 is a free data retrieval call binding the contract method 0x792c7f3e. +// +// Solidity: function dummy54() pure returns(uint256) +func (_Contract *ContractCaller) Dummy54(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy54") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy54 is a free data retrieval call binding the contract method 0x792c7f3e. +// +// Solidity: function dummy54() pure returns(uint256) +func (_Contract *ContractSession) Dummy54() (*big.Int, error) { + return _Contract.Contract.Dummy54(&_Contract.CallOpts) +} + +// Dummy54 is a free data retrieval call binding the contract method 0x792c7f3e. +// +// Solidity: function dummy54() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy54() (*big.Int, error) { + return _Contract.Contract.Dummy54(&_Contract.CallOpts) +} + +// Dummy55 is a free data retrieval call binding the contract method 0x7dffdc32. +// +// Solidity: function dummy55() pure returns(uint256) +func (_Contract *ContractCaller) Dummy55(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy55") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy55 is a free data retrieval call binding the contract method 0x7dffdc32. +// +// Solidity: function dummy55() pure returns(uint256) +func (_Contract *ContractSession) Dummy55() (*big.Int, error) { + return _Contract.Contract.Dummy55(&_Contract.CallOpts) +} + +// Dummy55 is a free data retrieval call binding the contract method 0x7dffdc32. +// +// Solidity: function dummy55() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy55() (*big.Int, error) { + return _Contract.Contract.Dummy55(&_Contract.CallOpts) +} + +// Dummy56 is a free data retrieval call binding the contract method 0xa891d4d4. +// +// Solidity: function dummy56() pure returns(uint256) +func (_Contract *ContractCaller) Dummy56(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy56") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy56 is a free data retrieval call binding the contract method 0xa891d4d4. +// +// Solidity: function dummy56() pure returns(uint256) +func (_Contract *ContractSession) Dummy56() (*big.Int, error) { + return _Contract.Contract.Dummy56(&_Contract.CallOpts) +} + +// Dummy56 is a free data retrieval call binding the contract method 0xa891d4d4. +// +// Solidity: function dummy56() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy56() (*big.Int, error) { + return _Contract.Contract.Dummy56(&_Contract.CallOpts) +} + +// Dummy57 is a free data retrieval call binding the contract method 0x74f83d02. +// +// Solidity: function dummy57() pure returns(uint256) +func (_Contract *ContractCaller) Dummy57(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy57") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy57 is a free data retrieval call binding the contract method 0x74f83d02. +// +// Solidity: function dummy57() pure returns(uint256) +func (_Contract *ContractSession) Dummy57() (*big.Int, error) { + return _Contract.Contract.Dummy57(&_Contract.CallOpts) +} + +// Dummy57 is a free data retrieval call binding the contract method 0x74f83d02. +// +// Solidity: function dummy57() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy57() (*big.Int, error) { + return _Contract.Contract.Dummy57(&_Contract.CallOpts) +} + +// Dummy58 is a free data retrieval call binding the contract method 0x54c27920. +// +// Solidity: function dummy58() pure returns(uint256) +func (_Contract *ContractCaller) Dummy58(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy58") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy58 is a free data retrieval call binding the contract method 0x54c27920. +// +// Solidity: function dummy58() pure returns(uint256) +func (_Contract *ContractSession) Dummy58() (*big.Int, error) { + return _Contract.Contract.Dummy58(&_Contract.CallOpts) +} + +// Dummy58 is a free data retrieval call binding the contract method 0x54c27920. +// +// Solidity: function dummy58() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy58() (*big.Int, error) { + return _Contract.Contract.Dummy58(&_Contract.CallOpts) +} + +// Dummy59 is a free data retrieval call binding the contract method 0x77c0209e. +// +// Solidity: function dummy59() pure returns(uint256) +func (_Contract *ContractCaller) Dummy59(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy59") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy59 is a free data retrieval call binding the contract method 0x77c0209e. +// +// Solidity: function dummy59() pure returns(uint256) +func (_Contract *ContractSession) Dummy59() (*big.Int, error) { + return _Contract.Contract.Dummy59(&_Contract.CallOpts) +} + +// Dummy59 is a free data retrieval call binding the contract method 0x77c0209e. +// +// Solidity: function dummy59() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy59() (*big.Int, error) { + return _Contract.Contract.Dummy59(&_Contract.CallOpts) +} + +// Dummy6 is a free data retrieval call binding the contract method 0x4128a85d. +// +// Solidity: function dummy6() pure returns(uint256) +func (_Contract *ContractCaller) Dummy6(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy6") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy6 is a free data retrieval call binding the contract method 0x4128a85d. +// +// Solidity: function dummy6() pure returns(uint256) +func (_Contract *ContractSession) Dummy6() (*big.Int, error) { + return _Contract.Contract.Dummy6(&_Contract.CallOpts) +} + +// Dummy6 is a free data retrieval call binding the contract method 0x4128a85d. +// +// Solidity: function dummy6() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy6() (*big.Int, error) { + return _Contract.Contract.Dummy6(&_Contract.CallOpts) +} + +// Dummy60 is a free data retrieval call binding the contract method 0x34517f0b. +// +// Solidity: function dummy60() pure returns(uint256) +func (_Contract *ContractCaller) Dummy60(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy60") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy60 is a free data retrieval call binding the contract method 0x34517f0b. +// +// Solidity: function dummy60() pure returns(uint256) +func (_Contract *ContractSession) Dummy60() (*big.Int, error) { + return _Contract.Contract.Dummy60(&_Contract.CallOpts) +} + +// Dummy60 is a free data retrieval call binding the contract method 0x34517f0b. +// +// Solidity: function dummy60() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy60() (*big.Int, error) { + return _Contract.Contract.Dummy60(&_Contract.CallOpts) +} + +// Dummy61 is a free data retrieval call binding the contract method 0xe2d27530. +// +// Solidity: function dummy61() pure returns(uint256) +func (_Contract *ContractCaller) Dummy61(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy61") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy61 is a free data retrieval call binding the contract method 0xe2d27530. +// +// Solidity: function dummy61() pure returns(uint256) +func (_Contract *ContractSession) Dummy61() (*big.Int, error) { + return _Contract.Contract.Dummy61(&_Contract.CallOpts) +} + +// Dummy61 is a free data retrieval call binding the contract method 0xe2d27530. +// +// Solidity: function dummy61() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy61() (*big.Int, error) { + return _Contract.Contract.Dummy61(&_Contract.CallOpts) +} + +// Dummy62 is a free data retrieval call binding the contract method 0xf5f57381. +// +// Solidity: function dummy62() pure returns(uint256) +func (_Contract *ContractCaller) Dummy62(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy62") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy62 is a free data retrieval call binding the contract method 0xf5f57381. +// +// Solidity: function dummy62() pure returns(uint256) +func (_Contract *ContractSession) Dummy62() (*big.Int, error) { + return _Contract.Contract.Dummy62(&_Contract.CallOpts) +} + +// Dummy62 is a free data retrieval call binding the contract method 0xf5f57381. +// +// Solidity: function dummy62() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy62() (*big.Int, error) { + return _Contract.Contract.Dummy62(&_Contract.CallOpts) +} + +// Dummy63 is a free data retrieval call binding the contract method 0x7a319c18. +// +// Solidity: function dummy63() pure returns(uint256) +func (_Contract *ContractCaller) Dummy63(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy63") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy63 is a free data retrieval call binding the contract method 0x7a319c18. +// +// Solidity: function dummy63() pure returns(uint256) +func (_Contract *ContractSession) Dummy63() (*big.Int, error) { + return _Contract.Contract.Dummy63(&_Contract.CallOpts) +} + +// Dummy63 is a free data retrieval call binding the contract method 0x7a319c18. +// +// Solidity: function dummy63() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy63() (*big.Int, error) { + return _Contract.Contract.Dummy63(&_Contract.CallOpts) +} + +// Dummy64 is a free data retrieval call binding the contract method 0xad8f4221. +// +// Solidity: function dummy64() pure returns(uint256) +func (_Contract *ContractCaller) Dummy64(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy64") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy64 is a free data retrieval call binding the contract method 0xad8f4221. +// +// Solidity: function dummy64() pure returns(uint256) +func (_Contract *ContractSession) Dummy64() (*big.Int, error) { + return _Contract.Contract.Dummy64(&_Contract.CallOpts) +} + +// Dummy64 is a free data retrieval call binding the contract method 0xad8f4221. +// +// Solidity: function dummy64() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy64() (*big.Int, error) { + return _Contract.Contract.Dummy64(&_Contract.CallOpts) +} + +// Dummy65 is a free data retrieval call binding the contract method 0x1f449589. +// +// Solidity: function dummy65() pure returns(uint256) +func (_Contract *ContractCaller) Dummy65(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy65") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy65 is a free data retrieval call binding the contract method 0x1f449589. +// +// Solidity: function dummy65() pure returns(uint256) +func (_Contract *ContractSession) Dummy65() (*big.Int, error) { + return _Contract.Contract.Dummy65(&_Contract.CallOpts) +} + +// Dummy65 is a free data retrieval call binding the contract method 0x1f449589. +// +// Solidity: function dummy65() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy65() (*big.Int, error) { + return _Contract.Contract.Dummy65(&_Contract.CallOpts) +} + +// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. +// +// Solidity: function dummy66() pure returns(uint256) +func (_Contract *ContractCaller) Dummy66(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy66") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. +// +// Solidity: function dummy66() pure returns(uint256) +func (_Contract *ContractSession) Dummy66() (*big.Int, error) { + return _Contract.Contract.Dummy66(&_Contract.CallOpts) +} + +// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. +// +// Solidity: function dummy66() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy66() (*big.Int, error) { + return _Contract.Contract.Dummy66(&_Contract.CallOpts) +} + +// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. +// +// Solidity: function dummy67() pure returns(uint256) +func (_Contract *ContractCaller) Dummy67(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy67") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. +// +// Solidity: function dummy67() pure returns(uint256) +func (_Contract *ContractSession) Dummy67() (*big.Int, error) { + return _Contract.Contract.Dummy67(&_Contract.CallOpts) +} + +// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. +// +// Solidity: function dummy67() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy67() (*big.Int, error) { + return _Contract.Contract.Dummy67(&_Contract.CallOpts) +} + +// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. +// +// Solidity: function dummy68() pure returns(uint256) +func (_Contract *ContractCaller) Dummy68(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy68") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. +// +// Solidity: function dummy68() pure returns(uint256) +func (_Contract *ContractSession) Dummy68() (*big.Int, error) { + return _Contract.Contract.Dummy68(&_Contract.CallOpts) +} + +// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. +// +// Solidity: function dummy68() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy68() (*big.Int, error) { + return _Contract.Contract.Dummy68(&_Contract.CallOpts) +} + +// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. +// +// Solidity: function dummy69() pure returns(uint256) +func (_Contract *ContractCaller) Dummy69(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy69") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. +// +// Solidity: function dummy69() pure returns(uint256) +func (_Contract *ContractSession) Dummy69() (*big.Int, error) { + return _Contract.Contract.Dummy69(&_Contract.CallOpts) +} + +// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. +// +// Solidity: function dummy69() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy69() (*big.Int, error) { + return _Contract.Contract.Dummy69(&_Contract.CallOpts) +} + +// Dummy7 is a free data retrieval call binding the contract method 0xf26c779b. +// +// Solidity: function dummy7() pure returns(uint256) +func (_Contract *ContractCaller) Dummy7(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy7") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy7 is a free data retrieval call binding the contract method 0xf26c779b. +// +// Solidity: function dummy7() pure returns(uint256) +func (_Contract *ContractSession) Dummy7() (*big.Int, error) { + return _Contract.Contract.Dummy7(&_Contract.CallOpts) +} + +// Dummy7 is a free data retrieval call binding the contract method 0xf26c779b. +// +// Solidity: function dummy7() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy7() (*big.Int, error) { + return _Contract.Contract.Dummy7(&_Contract.CallOpts) +} + +// Dummy70 is a free data retrieval call binding the contract method 0xbbe23132. +// +// Solidity: function dummy70() pure returns(uint256) +func (_Contract *ContractCaller) Dummy70(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy70") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy70 is a free data retrieval call binding the contract method 0xbbe23132. +// +// Solidity: function dummy70() pure returns(uint256) +func (_Contract *ContractSession) Dummy70() (*big.Int, error) { + return _Contract.Contract.Dummy70(&_Contract.CallOpts) +} + +// Dummy70 is a free data retrieval call binding the contract method 0xbbe23132. +// +// Solidity: function dummy70() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy70() (*big.Int, error) { + return _Contract.Contract.Dummy70(&_Contract.CallOpts) +} + +// Dummy71 is a free data retrieval call binding the contract method 0xf4978b04. +// +// Solidity: function dummy71() pure returns(uint256) +func (_Contract *ContractCaller) Dummy71(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy71") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy71 is a free data retrieval call binding the contract method 0xf4978b04. +// +// Solidity: function dummy71() pure returns(uint256) +func (_Contract *ContractSession) Dummy71() (*big.Int, error) { + return _Contract.Contract.Dummy71(&_Contract.CallOpts) +} + +// Dummy71 is a free data retrieval call binding the contract method 0xf4978b04. +// +// Solidity: function dummy71() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy71() (*big.Int, error) { + return _Contract.Contract.Dummy71(&_Contract.CallOpts) +} + +// Dummy72 is a free data retrieval call binding the contract method 0x1f29783f. +// +// Solidity: function dummy72() pure returns(uint256) +func (_Contract *ContractCaller) Dummy72(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy72") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy72 is a free data retrieval call binding the contract method 0x1f29783f. +// +// Solidity: function dummy72() pure returns(uint256) +func (_Contract *ContractSession) Dummy72() (*big.Int, error) { + return _Contract.Contract.Dummy72(&_Contract.CallOpts) +} + +// Dummy72 is a free data retrieval call binding the contract method 0x1f29783f. +// +// Solidity: function dummy72() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy72() (*big.Int, error) { + return _Contract.Contract.Dummy72(&_Contract.CallOpts) +} + +// Dummy73 is a free data retrieval call binding the contract method 0x595471b8. +// +// Solidity: function dummy73() pure returns(uint256) +func (_Contract *ContractCaller) Dummy73(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy73") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy73 is a free data retrieval call binding the contract method 0x595471b8. +// +// Solidity: function dummy73() pure returns(uint256) +func (_Contract *ContractSession) Dummy73() (*big.Int, error) { + return _Contract.Contract.Dummy73(&_Contract.CallOpts) +} + +// Dummy73 is a free data retrieval call binding the contract method 0x595471b8. +// +// Solidity: function dummy73() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy73() (*big.Int, error) { + return _Contract.Contract.Dummy73(&_Contract.CallOpts) +} + +// Dummy74 is a free data retrieval call binding the contract method 0xb4c48668. +// +// Solidity: function dummy74() pure returns(uint256) +func (_Contract *ContractCaller) Dummy74(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy74") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy74 is a free data retrieval call binding the contract method 0xb4c48668. +// +// Solidity: function dummy74() pure returns(uint256) +func (_Contract *ContractSession) Dummy74() (*big.Int, error) { + return _Contract.Contract.Dummy74(&_Contract.CallOpts) +} + +// Dummy74 is a free data retrieval call binding the contract method 0xb4c48668. +// +// Solidity: function dummy74() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy74() (*big.Int, error) { + return _Contract.Contract.Dummy74(&_Contract.CallOpts) +} + +// Dummy75 is a free data retrieval call binding the contract method 0x378c5382. +// +// Solidity: function dummy75() pure returns(uint256) +func (_Contract *ContractCaller) Dummy75(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy75") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy75 is a free data retrieval call binding the contract method 0x378c5382. +// +// Solidity: function dummy75() pure returns(uint256) +func (_Contract *ContractSession) Dummy75() (*big.Int, error) { + return _Contract.Contract.Dummy75(&_Contract.CallOpts) +} + +// Dummy75 is a free data retrieval call binding the contract method 0x378c5382. +// +// Solidity: function dummy75() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy75() (*big.Int, error) { + return _Contract.Contract.Dummy75(&_Contract.CallOpts) +} + +// Dummy8 is a free data retrieval call binding the contract method 0x19cf6a91. +// +// Solidity: function dummy8() pure returns(uint256) +func (_Contract *ContractCaller) Dummy8(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy8") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy8 is a free data retrieval call binding the contract method 0x19cf6a91. +// +// Solidity: function dummy8() pure returns(uint256) +func (_Contract *ContractSession) Dummy8() (*big.Int, error) { + return _Contract.Contract.Dummy8(&_Contract.CallOpts) +} + +// Dummy8 is a free data retrieval call binding the contract method 0x19cf6a91. +// +// Solidity: function dummy8() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy8() (*big.Int, error) { + return _Contract.Contract.Dummy8(&_Contract.CallOpts) +} + +// Dummy9 is a free data retrieval call binding the contract method 0x58b6a9bd. +// +// Solidity: function dummy9() pure returns(uint256) +func (_Contract *ContractCaller) Dummy9(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "dummy9") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy9 is a free data retrieval call binding the contract method 0x58b6a9bd. +// +// Solidity: function dummy9() pure returns(uint256) +func (_Contract *ContractSession) Dummy9() (*big.Int, error) { + return _Contract.Contract.Dummy9(&_Contract.CallOpts) +} + +// Dummy9 is a free data retrieval call binding the contract method 0x58b6a9bd. +// +// Solidity: function dummy9() pure returns(uint256) +func (_Contract *ContractCallerSession) Dummy9() (*big.Int, error) { + return _Contract.Contract.Dummy9(&_Contract.CallOpts) +} + // Name is a free data retrieval call binding the contract method 0x06fdde03. // // Solidity: function name() view returns(string) @@ -482,6 +2807,405 @@ func (_Contract *ContractTransactorSession) TransferFrom(from common.Address, to return _Contract.Contract.TransferFrom(&_Contract.TransactOpts, from, to, value) } +// TransferFrom1 is a paid mutator transaction binding the contract method 0xbb9bfe06. +// +// Solidity: function transferFrom1(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom1(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom1", from, to, value) +} + +// TransferFrom1 is a paid mutator transaction binding the contract method 0xbb9bfe06. +// +// Solidity: function transferFrom1(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom1(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom1(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom1 is a paid mutator transaction binding the contract method 0xbb9bfe06. +// +// Solidity: function transferFrom1(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom1(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom1(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom10 is a paid mutator transaction binding the contract method 0xb1802b9a. +// +// Solidity: function transferFrom10(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom10(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom10", from, to, value) +} + +// TransferFrom10 is a paid mutator transaction binding the contract method 0xb1802b9a. +// +// Solidity: function transferFrom10(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom10(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom10(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom10 is a paid mutator transaction binding the contract method 0xb1802b9a. +// +// Solidity: function transferFrom10(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom10(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom10(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom11 is a paid mutator transaction binding the contract method 0xc2be97e3. +// +// Solidity: function transferFrom11(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom11(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom11", from, to, value) +} + +// TransferFrom11 is a paid mutator transaction binding the contract method 0xc2be97e3. +// +// Solidity: function transferFrom11(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom11(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom11(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom11 is a paid mutator transaction binding the contract method 0xc2be97e3. +// +// Solidity: function transferFrom11(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom11(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom11(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom12 is a paid mutator transaction binding the contract method 0x44050a28. +// +// Solidity: function transferFrom12(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom12(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom12", from, to, value) +} + +// TransferFrom12 is a paid mutator transaction binding the contract method 0x44050a28. +// +// Solidity: function transferFrom12(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom12(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom12(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom12 is a paid mutator transaction binding the contract method 0x44050a28. +// +// Solidity: function transferFrom12(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom12(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom12(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom13 is a paid mutator transaction binding the contract method 0xacc5aee9. +// +// Solidity: function transferFrom13(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom13(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom13", from, to, value) +} + +// TransferFrom13 is a paid mutator transaction binding the contract method 0xacc5aee9. +// +// Solidity: function transferFrom13(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom13(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom13(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom13 is a paid mutator transaction binding the contract method 0xacc5aee9. +// +// Solidity: function transferFrom13(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom13(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom13(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom14 is a paid mutator transaction binding the contract method 0x1bbffe6f. +// +// Solidity: function transferFrom14(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom14(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom14", from, to, value) +} + +// TransferFrom14 is a paid mutator transaction binding the contract method 0x1bbffe6f. +// +// Solidity: function transferFrom14(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom14(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom14(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom14 is a paid mutator transaction binding the contract method 0x1bbffe6f. +// +// Solidity: function transferFrom14(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom14(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom14(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom15 is a paid mutator transaction binding the contract method 0x8789ca67. +// +// Solidity: function transferFrom15(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom15(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom15", from, to, value) +} + +// TransferFrom15 is a paid mutator transaction binding the contract method 0x8789ca67. +// +// Solidity: function transferFrom15(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom15(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom15(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom15 is a paid mutator transaction binding the contract method 0x8789ca67. +// +// Solidity: function transferFrom15(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom15(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom15(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom16 is a paid mutator transaction binding the contract method 0x39e0bd12. +// +// Solidity: function transferFrom16(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom16(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom16", from, to, value) +} + +// TransferFrom16 is a paid mutator transaction binding the contract method 0x39e0bd12. +// +// Solidity: function transferFrom16(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom16(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom16(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom16 is a paid mutator transaction binding the contract method 0x39e0bd12. +// +// Solidity: function transferFrom16(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom16(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom16(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom17 is a paid mutator transaction binding the contract method 0x291c3bd7. +// +// Solidity: function transferFrom17(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom17(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom17", from, to, value) +} + +// TransferFrom17 is a paid mutator transaction binding the contract method 0x291c3bd7. +// +// Solidity: function transferFrom17(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom17(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom17(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom17 is a paid mutator transaction binding the contract method 0x291c3bd7. +// +// Solidity: function transferFrom17(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom17(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom17(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom18 is a paid mutator transaction binding the contract method 0x657b6ef7. +// +// Solidity: function transferFrom18(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom18(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom18", from, to, value) +} + +// TransferFrom18 is a paid mutator transaction binding the contract method 0x657b6ef7. +// +// Solidity: function transferFrom18(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom18(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom18(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom18 is a paid mutator transaction binding the contract method 0x657b6ef7. +// +// Solidity: function transferFrom18(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom18(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom18(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom19 is a paid mutator transaction binding the contract method 0xeb4329c8. +// +// Solidity: function transferFrom19(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom19(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom19", from, to, value) +} + +// TransferFrom19 is a paid mutator transaction binding the contract method 0xeb4329c8. +// +// Solidity: function transferFrom19(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom19(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom19(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom19 is a paid mutator transaction binding the contract method 0xeb4329c8. +// +// Solidity: function transferFrom19(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom19(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom19(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom2 is a paid mutator transaction binding the contract method 0x6c12ed28. +// +// Solidity: function transferFrom2(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom2(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom2", from, to, value) +} + +// TransferFrom2 is a paid mutator transaction binding the contract method 0x6c12ed28. +// +// Solidity: function transferFrom2(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom2(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom2(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom2 is a paid mutator transaction binding the contract method 0x6c12ed28. +// +// Solidity: function transferFrom2(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom2(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom2(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom3 is a paid mutator transaction binding the contract method 0x1b17c65c. +// +// Solidity: function transferFrom3(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom3(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom3", from, to, value) +} + +// TransferFrom3 is a paid mutator transaction binding the contract method 0x1b17c65c. +// +// Solidity: function transferFrom3(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom3(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom3(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom3 is a paid mutator transaction binding the contract method 0x1b17c65c. +// +// Solidity: function transferFrom3(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom3(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom3(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom4 is a paid mutator transaction binding the contract method 0x3a131990. +// +// Solidity: function transferFrom4(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom4(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom4", from, to, value) +} + +// TransferFrom4 is a paid mutator transaction binding the contract method 0x3a131990. +// +// Solidity: function transferFrom4(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom4(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom4(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom4 is a paid mutator transaction binding the contract method 0x3a131990. +// +// Solidity: function transferFrom4(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom4(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom4(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom5 is a paid mutator transaction binding the contract method 0x0460faf6. +// +// Solidity: function transferFrom5(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom5(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom5", from, to, value) +} + +// TransferFrom5 is a paid mutator transaction binding the contract method 0x0460faf6. +// +// Solidity: function transferFrom5(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom5(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom5(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom5 is a paid mutator transaction binding the contract method 0x0460faf6. +// +// Solidity: function transferFrom5(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom5(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom5(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom6 is a paid mutator transaction binding the contract method 0x7c66673e. +// +// Solidity: function transferFrom6(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom6(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom6", from, to, value) +} + +// TransferFrom6 is a paid mutator transaction binding the contract method 0x7c66673e. +// +// Solidity: function transferFrom6(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom6(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom6(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom6 is a paid mutator transaction binding the contract method 0x7c66673e. +// +// Solidity: function transferFrom6(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom6(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom6(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom7 is a paid mutator transaction binding the contract method 0xfaf35ced. +// +// Solidity: function transferFrom7(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom7(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom7", from, to, value) +} + +// TransferFrom7 is a paid mutator transaction binding the contract method 0xfaf35ced. +// +// Solidity: function transferFrom7(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom7(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom7(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom7 is a paid mutator transaction binding the contract method 0xfaf35ced. +// +// Solidity: function transferFrom7(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom7(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom7(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom8 is a paid mutator transaction binding the contract method 0x552a1b56. +// +// Solidity: function transferFrom8(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom8(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom8", from, to, value) +} + +// TransferFrom8 is a paid mutator transaction binding the contract method 0x552a1b56. +// +// Solidity: function transferFrom8(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom8(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom8(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom8 is a paid mutator transaction binding the contract method 0x552a1b56. +// +// Solidity: function transferFrom8(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom8(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom8(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom9 is a paid mutator transaction binding the contract method 0x4f7bd75a. +// +// Solidity: function transferFrom9(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactor) TransferFrom9(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "transferFrom9", from, to, value) +} + +// TransferFrom9 is a paid mutator transaction binding the contract method 0x4f7bd75a. +// +// Solidity: function transferFrom9(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractSession) TransferFrom9(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom9(&_Contract.TransactOpts, from, to, value) +} + +// TransferFrom9 is a paid mutator transaction binding the contract method 0x4f7bd75a. +// +// Solidity: function transferFrom9(address from, address to, uint256 value) returns(bool) +func (_Contract *ContractTransactorSession) TransferFrom9(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Contract.Contract.TransferFrom9(&_Contract.TransactOpts, from, to, value) +} + // ContractApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the Contract contract. type ContractApprovalIterator struct { Event *ContractApproval // Event containing the contract specifics and raw log diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol index 28dc8454..29fe7221 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol @@ -24,8 +24,6 @@ contract StateBloatToken { symbol = "SBT"; decimals = 18; salt = _salt; - - // Initialize with some state totalSupply = 1000000 * 10 ** decimals; balanceOf[msg.sender] = totalSupply; emit Transfer(address(0), msg.sender, totalSupply); @@ -58,4 +56,570 @@ contract StateBloatToken { emit Transfer(from, to, value); return true; } + + // Dummy functions to increase bytecode size + function dummy1() public pure returns (uint256) { + return 1; + } + + function dummy2() public pure returns (uint256) { + return 2; + } + + function dummy3() public pure returns (uint256) { + return 3; + } + + function dummy4() public pure returns (uint256) { + return 4; + } + + function dummy5() public pure returns (uint256) { + return 5; + } + + function dummy6() public pure returns (uint256) { + return 6; + } + + function dummy7() public pure returns (uint256) { + return 7; + } + + function dummy8() public pure returns (uint256) { + return 8; + } + + function dummy9() public pure returns (uint256) { + return 9; + } + + function dummy10() public pure returns (uint256) { + return 10; + } + + function dummy11() public pure returns (uint256) { + return 11; + } + + function dummy12() public pure returns (uint256) { + return 12; + } + + function dummy13() public pure returns (uint256) { + return 13; + } + + function dummy14() public pure returns (uint256) { + return 14; + } + + function dummy15() public pure returns (uint256) { + return 15; + } + + function dummy16() public pure returns (uint256) { + return 16; + } + + function dummy17() public pure returns (uint256) { + return 17; + } + + function dummy18() public pure returns (uint256) { + return 18; + } + + function dummy19() public pure returns (uint256) { + return 19; + } + + function dummy20() public pure returns (uint256) { + return 20; + } + + function dummy21() public pure returns (uint256) { + return 21; + } + + function dummy22() public pure returns (uint256) { + return 22; + } + + function dummy23() public pure returns (uint256) { + return 23; + } + + function dummy24() public pure returns (uint256) { + return 24; + } + + function dummy25() public pure returns (uint256) { + return 25; + } + + function dummy26() public pure returns (uint256) { + return 26; + } + + function dummy27() public pure returns (uint256) { + return 27; + } + + function dummy28() public pure returns (uint256) { + return 28; + } + + function dummy29() public pure returns (uint256) { + return 29; + } + + function dummy30() public pure returns (uint256) { + return 30; + } + + function dummy31() public pure returns (uint256) { + return 31; + } + + function dummy32() public pure returns (uint256) { + return 32; + } + + function dummy33() public pure returns (uint256) { + return 33; + } + + function dummy34() public pure returns (uint256) { + return 34; + } + + function dummy35() public pure returns (uint256) { + return 35; + } + + function dummy36() public pure returns (uint256) { + return 36; + } + + function dummy37() public pure returns (uint256) { + return 37; + } + + function dummy38() public pure returns (uint256) { + return 38; + } + + function dummy39() public pure returns (uint256) { + return 39; + } + + function dummy40() public pure returns (uint256) { + return 40; + } + + function dummy41() public pure returns (uint256) { + return 41; + } + + function dummy42() public pure returns (uint256) { + return 42; + } + + function dummy43() public pure returns (uint256) { + return 43; + } + + function dummy44() public pure returns (uint256) { + return 44; + } + + function dummy45() public pure returns (uint256) { + return 45; + } + + function dummy46() public pure returns (uint256) { + return 46; + } + + function dummy47() public pure returns (uint256) { + return 47; + } + + function dummy48() public pure returns (uint256) { + return 48; + } + + function dummy49() public pure returns (uint256) { + return 49; + } + + function dummy50() public pure returns (uint256) { + return 50; + } + + function dummy51() public pure returns (uint256) { + return 51; + } + + function dummy52() public pure returns (uint256) { + return 52; + } + + function dummy53() public pure returns (uint256) { + return 53; + } + + function dummy54() public pure returns (uint256) { + return 54; + } + + function dummy55() public pure returns (uint256) { + return 55; + } + + function dummy56() public pure returns (uint256) { + return 56; + } + + function dummy57() public pure returns (uint256) { + return 57; + } + + function dummy58() public pure returns (uint256) { + return 58; + } + + function dummy59() public pure returns (uint256) { + return 59; + } + + function dummy60() public pure returns (uint256) { + return 60; + } + + function dummy61() public pure returns (uint256) { + return 61; + } + + function dummy62() public pure returns (uint256) { + return 62; + } + + function dummy63() public pure returns (uint256) { + return 63; + } + + function dummy64() public pure returns (uint256) { + return 64; + } + + function dummy65() public pure returns (uint256) { + return 65; + } + + function dummy66() public pure returns (uint256) { + return 66; + } + + function dummy67() public pure returns (uint256) { + return 67; + } + + function dummy68() public pure returns (uint256) { + return 68; + } + + function dummy69() public pure returns (uint256) { + return 69; + } + + function dummy70() public pure returns (uint256) { + return 70; + } + + function dummy71() public pure returns (uint256) { + return 71; + } + + function dummy72() public pure returns (uint256) { + return 72; + } + + function dummy73() public pure returns (uint256) { + return 73; + } + + function dummy74() public pure returns (uint256) { + return 74; + } + + function dummy75() public pure returns (uint256) { + return 75; + } + + function transferFrom1( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom2( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom3( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom4( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom5( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom6( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom7( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom8( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom9( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom10( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom11( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom12( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom13( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom14( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom15( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom16( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "Insufficient balance"); + require(allowance[from][msg.sender] >= value, "Insufficient allowance"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom17( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "A"); + require(allowance[from][msg.sender] >= value, "B"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom18( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "A"); + require(allowance[from][msg.sender] >= value, "B"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } + + function transferFrom19( + address from, + address to, + uint256 value + ) public returns (bool) { + require(balanceOf[from] >= value, "A"); + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + emit Transfer(from, to, value); + return true; + } } From e29266981ff33d80d0e4c366b2087fedfb9113d6 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Fri, 23 May 2025 09:45:47 +0200 Subject: [PATCH 12/39] feat(contract-deploy): enhance contract deployment scenario and logging - Updated the contract deployment scenario to log deployed contract addresses and gas used. - Added functionality to write deployed addresses to a JSON file for easier tracking. - Removed gas-per-block validation and adjusted wallet count logic. - Improved README with instructions for running against a local Anvil node without Go tests. --- README.md | 26 +- scenarios/scenarios.go | 2 + .../statebloat/contract_deploy/README.md | 40 ++- .../contract_deploy/contract_deploy.go | 168 ++++++------- .../contract_deploy/contract_deploy_test.go | 237 ------------------ 5 files changed, 125 insertions(+), 348 deletions(-) delete mode 100644 scenarios/statebloat/contract_deploy/contract_deploy_test.go diff --git a/README.md b/README.md index 8b602c8c..d5dd212f 100644 --- a/README.md +++ b/README.md @@ -29,19 +29,19 @@ All scenarios require: Spamoor provides multiple scenarios for different transaction types: -| Scenario | Description | -|----------|-------------| -| [`eoatx`](./scenarios/eoatx/README.md) | **EOA Transactions**
Send standard EOA transactions with configurable amounts and targets | -| [`erctx`](./scenarios/erctx/README.md) | **ERC20 Transactions**
Deploy a ERC20 contract and transfer tokens | -| [`deploytx`](./scenarios/deploytx/README.md) | **Contract Deployments**
Deploy contracts with custom bytecode | -| [`deploy-destruct`](./scenarios/deploy-destruct/README.md) | **Self-Destruct Deployments**
Deploy contracts that self-destruct | -| [`setcodetx`](./scenarios/setcodetx/README.md) | **Set Code Transactions**
Send EIP-7702 setcode-transactions with various settings | -| [`uniswap-swaps`](./scenarios/uniswap-swaps/README.md) | **Uniswap Swaps**
Deploy and perform token swaps on Uniswap V2 pools | -| [`blobs`](./scenarios/blobs/README.md) | **Blob Transactions**
Send blob transactions with random data | -| [`blob-replacements`](./scenarios/blob-replacements/README.md) | **Blob Replacements**
Send and replace blob transactions | -| [`blob-conflicting`](./scenarios/blob-conflicting/README.md) | **Conflicting Blobs**
Send conflicting blob and normal transactions | -| [`blob-combined`](./scenarios/blob-combined/README.md) | **Combined Blob Testing**
Randomized combination of all blob scenarios | -| [`gasburnertx`](./scenarios/gasburnertx/README.md) | **Gas Burner**
Send transactions that burn specific amounts of gas | +| Scenario | Description | +| -------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| [`eoatx`](./scenarios/eoatx/README.md) | **EOA Transactions**
Send standard EOA transactions with configurable amounts and targets | +| [`erctx`](./scenarios/erctx/README.md) | **ERC20 Transactions**
Deploy a ERC20 contract and transfer tokens | +| [`deploytx`](./scenarios/deploytx/README.md) | **Contract Deployments**
Deploy contracts with custom bytecode | +| [`deploy-destruct`](./scenarios/deploy-destruct/README.md) | **Self-Destruct Deployments**
Deploy contracts that self-destruct | +| [`setcodetx`](./scenarios/setcodetx/README.md) | **Set Code Transactions**
Send EIP-7702 setcode-transactions with various settings | +| [`uniswap-swaps`](./scenarios/uniswap-swaps/README.md) | **Uniswap Swaps**
Deploy and perform token swaps on Uniswap V2 pools | +| [`blobs`](./scenarios/blobs/README.md) | **Blob Transactions**
Send blob transactions with random data | +| [`blob-replacements`](./scenarios/blob-replacements/README.md) | **Blob Replacements**
Send and replace blob transactions | +| [`blob-conflicting`](./scenarios/blob-conflicting/README.md) | **Conflicting Blobs**
Send conflicting blob and normal transactions | +| [`blob-combined`](./scenarios/blob-combined/README.md) | **Combined Blob Testing**
Randomized combination of all blob scenarios | +| [`gasburnertx`](./scenarios/gasburnertx/README.md) | **Gas Burner**
Send transactions that burn specific amounts of gas | ## Daemon Mode diff --git a/scenarios/scenarios.go b/scenarios/scenarios.go index e0f32a82..6515fb6f 100644 --- a/scenarios/scenarios.go +++ b/scenarios/scenarios.go @@ -13,6 +13,7 @@ import ( "github.com/ethpandaops/spamoor/scenarios/erctx" "github.com/ethpandaops/spamoor/scenarios/gasburnertx" "github.com/ethpandaops/spamoor/scenarios/setcodetx" + contractdeploy "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy" uniswapswaps "github.com/ethpandaops/spamoor/scenarios/uniswap-swaps" "github.com/ethpandaops/spamoor/scenarios/wallets" ) @@ -30,6 +31,7 @@ var ScenarioDescriptors = []*scenariotypes.ScenarioDescriptor{ &setcodetx.ScenarioDescriptor, &uniswapswaps.ScenarioDescriptor, &wallets.ScenarioDescriptor, + &contractdeploy.ScenarioDescriptor, } func GetScenario(name string) *scenariotypes.ScenarioDescriptor { diff --git a/scenarios/statebloat/contract_deploy/README.md b/scenarios/statebloat/contract_deploy/README.md index ecd830a7..e6b70c0e 100644 --- a/scenarios/statebloat/contract_deploy/README.md +++ b/scenarios/statebloat/contract_deploy/README.md @@ -58,23 +58,43 @@ Deploy 1 contract per slot: spamoor statebloat/contract-deploy -p "" -h http://localhost:8545 -t 1 ``` -## Testing with Anvil +## Running Against a Local Anvil Node (without Go tests) + +You can run this scenario directly against your own Anvil node using the Spamoor CLI, without running Go tests. + +### 1. Start Anvil -1. Start Anvil: ```bash -anvil +anvil --hardfork pectra ``` -2. Run the scenario: +You can add other flags as needed (e.g., `--no-mining` if you want to control mining manually). + +### 2. Build Spamoor (if not already built) + ```bash -spamoor statebloat/contract-deploy -p "" -h http://localhost:8545 -c 1 +go build -o spamoor ./cmd/spamoor ``` -3. Verify state growth: +### 3. Run the Scenario + ```bash -# Get the contract address from the deployment receipt -# Then check the code size -cast code --rpc-url http://localhost:8545 +./spamoor statebloat/contract-deploy \ + --privkey \ + --rpchost http://localhost:8545 \ + --contracts-per-block 1 ``` -The code size should be exactly 24,576 bytes. \ No newline at end of file +- Replace `` with the private key of a funded account in your Anvil instance (Anvil prints these on startup). +- Adjust other flags as needed (`--contracts-per-block`, `--max-wallets`, etc.). + +### 4. Mining Notes + +- If you started Anvil with `--no-mining`, you will need to manually mine blocks (e.g., by calling `evm_mine` via RPC or using Anvil's console) to include the transactions. +- If you use Anvil's default mining mode, blocks will be mined automatically as transactions are sent. + +### 5. See All Flags + +```bash +./spamoor statebloat/contract-deploy --help +``` \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 482ddc8f..0eb63a48 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -3,16 +3,18 @@ package contractdeploy import ( "context" "crypto/rand" + "encoding/json" "fmt" "math/big" + "os" "sync" "sync/atomic" "time" - "golang.org/x/time/rate" "gopkg.in/yaml.v3" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/sirupsen/logrus" "github.com/spf13/pflag" @@ -21,7 +23,6 @@ import ( "github.com/ethpandaops/spamoor/scenariotypes" "github.com/ethpandaops/spamoor/spamoor" "github.com/ethpandaops/spamoor/txbuilder" - "github.com/ethpandaops/spamoor/utils" ) const ( @@ -30,15 +31,13 @@ const ( ) type ScenarioOptions struct { - MaxPending uint64 `yaml:"max_pending"` - MaxWallets uint64 `yaml:"max_wallets"` - Rebroadcast uint64 `yaml:"rebroadcast"` - BaseFee uint64 `yaml:"base_fee"` - TipFee uint64 `yaml:"tip_fee"` - GasPerBlock uint64 `yaml:"gas_per_block"` - ClientGroup string `yaml:"client_group"` - ContractsPerBlock uint64 `yaml:"contracts_per_block"` - MaxTransactions uint64 `yaml:"max_transactions"` // Maximum number of transactions to send (0 for unlimited) + MaxPending uint64 `yaml:"max_pending"` + MaxWallets uint64 `yaml:"max_wallets"` + Rebroadcast uint64 `yaml:"rebroadcast"` + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` + ClientGroup string `yaml:"client_group"` + MaxTransactions uint64 `yaml:"max_transactions"` // Maximum number of transactions to send (0 for unlimited) } type Scenario struct { @@ -48,19 +47,20 @@ type Scenario struct { pendingChan chan bool pendingWGroup sync.WaitGroup + + deployedAddresses []string + addressesMutex sync.Mutex } var ScenarioName = "contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ - MaxPending: 0, - MaxWallets: 0, - Rebroadcast: 1, - BaseFee: 20, - TipFee: 2, - GasPerBlock: 0, - ClientGroup: "default", - ContractsPerBlock: 1, - MaxTransactions: 0, // Default to unlimited + MaxPending: 0, + MaxWallets: 0, + Rebroadcast: 1, + BaseFee: 20, + TipFee: 2, + ClientGroup: "default", + MaxTransactions: 0, // Default to unlimited } var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ Name: ScenarioName, @@ -81,9 +81,7 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.Rebroadcast, "rebroadcast", ScenarioDefaultOptions.Rebroadcast, "Number of seconds to wait before re-broadcasting a transaction") flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Max fee per gas to use in transactions (in gwei)") flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") - flags.Uint64Var(&s.options.GasPerBlock, "gas-per-block", ScenarioDefaultOptions.GasPerBlock, "Target gas to use per block (will calculate number of contracts to deploy)") flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") - flags.Uint64Var(&s.options.ContractsPerBlock, "contracts-per-block", ScenarioDefaultOptions.ContractsPerBlock, "Number of contracts to deploy per block") flags.Uint64Var(&s.options.MaxTransactions, "max-transactions", ScenarioDefaultOptions.MaxTransactions, "Maximum number of transactions to send (0 for unlimited)") return nil } @@ -98,18 +96,10 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { } } - if s.options.GasPerBlock == 0 && s.options.ContractsPerBlock == 0 { - return fmt.Errorf("neither gas per block limit nor contracts per block set, must define at least one of them (see --help for list of all flags)") - } - if s.options.MaxWallets > 0 { walletPool.SetWalletCount(s.options.MaxWallets) } else { - if s.options.ContractsPerBlock*10 < 1000 { - walletPool.SetWalletCount(s.options.ContractsPerBlock * 10) - } else { - walletPool.SetWalletCount(1000) - } + walletPool.SetWalletCount(1000) } if s.options.MaxPending > 0 { @@ -133,74 +123,20 @@ func (s *Scenario) Run(ctx context.Context) error { s.logger.Infof("starting scenario: %s", ScenarioName) defer s.logger.Infof("scenario %s finished.", ScenarioName) - // Get block gas limit and validate contract deployment gas client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) if client == nil { return fmt.Errorf("no client available") } - block, err := client.GetEthClient().BlockByNumber(ctx, nil) - if err != nil { - return fmt.Errorf("failed to get latest block: %w", err) - } - blockGasLimit := block.GasLimit() - // Validate gas usage against block limit - if s.options.GasPerBlock > blockGasLimit { - return fmt.Errorf("gas per block (%d) exceeds block gas limit (%d)", s.options.GasPerBlock, blockGasLimit) - } - if s.options.ContractsPerBlock*GAS_PER_CONTRACT > blockGasLimit { - return fmt.Errorf("contracts per block (%d) requires %d gas, exceeding block gas limit (%d)", - s.options.ContractsPerBlock, s.options.ContractsPerBlock*GAS_PER_CONTRACT, blockGasLimit) - } - - // Calculate throughput based on gas per block or contracts per block - throughput := s.options.ContractsPerBlock - if s.options.GasPerBlock > 0 { - // Each deployment costs ~4.97M gas - throughput = s.options.GasPerBlock / GAS_PER_CONTRACT - if throughput == 0 { - throughput = 1 - } - s.logger.WithFields(logrus.Fields{ - "test": "contract-deploy", - "throughput": throughput, - "target_gas": s.options.GasPerBlock, - "gas_per_contract": GAS_PER_CONTRACT, - }).Info("calculated throughput") - } else { - // Calculate gas needed for the specified number of contracts - totalGas := GAS_PER_CONTRACT * s.options.ContractsPerBlock - s.logger.WithFields(logrus.Fields{ - "test": "contract-deploy", - "total_gas": totalGas, - "contracts": s.options.ContractsPerBlock, - "gas_per_contract": GAS_PER_CONTRACT, - }).Info("calculated gas") - } - - initialRate := rate.Limit(float64(throughput) / float64(utils.SecondsPerSlot)) - if initialRate == 0 { - initialRate = rate.Inf - } - limiter := rate.NewLimiter(initialRate, 1) + var deployTxHashesMu sync.Mutex + var deployTxHashes []common.Hash for { - // Check if we've reached the maximum number of transactions if s.options.MaxTransactions > 0 && txIdxCounter >= s.options.MaxTransactions { s.logger.Infof("reached maximum number of transactions (%d)", s.options.MaxTransactions) break } - if err := limiter.Wait(ctx); err != nil { - if ctx.Err() != nil { - break - } - - s.logger.Debugf("rate limited: %s", err.Error()) - time.Sleep(100 * time.Millisecond) - continue - } - txIdx := txIdxCounter txIdxCounter++ @@ -241,18 +177,74 @@ func (s *Scenario) Run(ctx context.Context) error { return } + // Collect tx hash for later receipt lookup + deployTxHashesMu.Lock() + deployTxHashes = append(deployTxHashes, tx.Hash()) + deployTxHashesMu.Unlock() + txCount.Add(1) }(txIdx, lastChan, currentChan) lastChan = currentChan } s.pendingWGroup.Wait() + s.logger.WithFields(logrus.Fields{ "test": "contract-deploy", "total_txs": txCount.Load(), "pending_txs": pendingCount.Load(), }).Info("finished sending transactions, awaiting block inclusion...") + // Wait for a new block to be mined + ethClient := client.GetEthClient() + startBlock, err := ethClient.BlockByNumber(ctx, nil) + if err != nil { + s.logger.Warnf("Failed to get current block: %v", err) + return err + } + startBlockNum := startBlock.NumberU64() + var latestBlockNum uint64 + for { + block, err := ethClient.BlockByNumber(ctx, nil) + if err != nil { + s.logger.Warnf("Failed to get block: %v", err) + return err + } + latestBlockNum = block.NumberU64() + if latestBlockNum > startBlockNum { + break + } + time.Sleep(2 * time.Second) + } + + // For each deployment tx, get the receipt and log contract address and gas used + var deployedAddresses []string + for _, txHash := range deployTxHashes { + receipt, err := ethClient.TransactionReceipt(ctx, txHash) + if err != nil { + s.logger.Warnf("Failed to get receipt for tx %s: %v", txHash.Hex(), err) + continue + } + if receipt.ContractAddress != (common.Address{}) { + addr := receipt.ContractAddress.Hex() + deployedAddresses = append(deployedAddresses, addr) + s.logger.Infof("Deployed contract at address: %s (gas used: %d)", addr, receipt.GasUsed) + } + } + + // Write deployed addresses to JSON file and log them + if len(deployedAddresses) > 0 { + file, err := os.Create("deployed_contracts.json") + if err == nil { + _ = json.NewEncoder(file).Encode(deployedAddresses) + file.Close() + s.logger.Infof("Wrote %d deployed contract addresses to deployed_contracts.json", len(deployedAddresses)) + } else { + s.logger.Warnf("Failed to write deployed_contracts.json: %v", err) + } + s.logger.Infof("Deployed contract addresses: %v", deployedAddresses) + } + return nil } @@ -281,7 +273,7 @@ func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) auth.Nonce = big.NewInt(int64(wallet.GetNonce())) auth.Value = big.NewInt(0) - auth.GasLimit = GAS_PER_CONTRACT // Gas for single contract deployment + auth.GasLimit = GAS_PER_CONTRACT + GAS_PER_CONTRACT*5/100 // Gas for single contract deployment // Set EIP-1559 fee parameters if s.options.BaseFee > 0 { diff --git a/scenarios/statebloat/contract_deploy/contract_deploy_test.go b/scenarios/statebloat/contract_deploy/contract_deploy_test.go deleted file mode 100644 index 653bd50d..00000000 --- a/scenarios/statebloat/contract_deploy/contract_deploy_test.go +++ /dev/null @@ -1,237 +0,0 @@ -package contractdeploy - -import ( - "context" - "os/exec" - "testing" - "time" - - "github.com/ethereum/go-ethereum/ethclient" - "github.com/holiman/uint256" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethpandaops/spamoor/spamoor" - "github.com/ethpandaops/spamoor/txbuilder" - "github.com/ethpandaops/spamoor/utils" -) - -type testFixture struct { - t *testing.T - cmd *exec.Cmd - client *ethclient.Client - ctx context.Context - logger *logrus.Entry - clientPool *spamoor.ClientPool - rootWallet *txbuilder.Wallet - txpool *txbuilder.TxPool - walletPool *spamoor.WalletPool - scenario *Scenario -} - -func setupTestFixture(t *testing.T) *testFixture { - // Start Anvil server with legacy transactions - cmd := exec.Command("anvil", "--hardfork", "pectra") - err := cmd.Start() - require.NoError(t, err) - - // Wait for Anvil to start - time.Sleep(2 * time.Second) - - // Connect to Anvil - client, err := ethclient.Dial("http://localhost:8545") - require.NoError(t, err) - - // Create client pool - ctx := context.Background() - logger := logrus.New().WithField("test", "contract-deploy") - clientPool := spamoor.NewClientPool(ctx, []string{"http://localhost:8545"}, logger) - err = clientPool.PrepareClients() - require.NoError(t, err) - - // Create root wallet using a pre-funded Anvil account - rootWallet, err := spamoor.InitRootWallet(ctx, "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", clientPool.GetClient(spamoor.SelectClientByIndex, 0, ""), logger) - require.NoError(t, err) - - // Create tx pool - txpool := txbuilder.NewTxPool(&txbuilder.TxPoolOptions{ - Context: ctx, - GetClientFn: func(index int, random bool) *txbuilder.Client { - mode := spamoor.SelectClientByIndex - if random { - mode = spamoor.SelectClientRandom - } - return clientPool.GetClient(mode, index, "") - }, - GetClientCountFn: func() int { - return len(clientPool.GetAllClients()) - }, - }) - - // Create wallet pool - walletPool := spamoor.NewWalletPool(ctx, logger, rootWallet, clientPool, txpool) - walletPool.SetWalletCount(1) - walletPool.SetRefillAmount(utils.EtherToWei(uint256.NewInt(1))) // 1 ETH - walletPool.SetRefillBalance(utils.EtherToWei(uint256.NewInt(1))) // 1 ETH - walletPool.SetRefillInterval(60) - - // Initialize wallet pool - err = walletPool.PrepareWallets(true) - require.NoError(t, err) - - // Create scenario instance - scenario := newScenario(logger).(*Scenario) - - return &testFixture{ - t: t, - cmd: cmd, - client: client, - ctx: ctx, - logger: logger, - clientPool: clientPool, - rootWallet: rootWallet, - txpool: txpool, - walletPool: walletPool, - scenario: scenario, - } -} - -func (f *testFixture) teardown() { - if f.cmd != nil && f.cmd.Process != nil { - f.cmd.Process.Kill() - } - if f.client != nil { - f.client.Close() - } -} - -func (f *testFixture) verifyContractDeployment(runCtx context.Context) { - // Verify contract deployment - block, err := f.client.BlockByNumber(runCtx, nil) - require.NoError(f.t, err) - assert.Greater(f.t, len(block.Transactions()), 0) - - // Get the expected number of contracts based on scenario config - expectedContracts := f.scenario.options.ContractsPerBlock - if f.scenario.options.GasPerBlock > 0 { - expectedContracts = f.scenario.options.GasPerBlock / GAS_PER_CONTRACT - if expectedContracts == 0 { - expectedContracts = 1 - } - } - - // Track deployed contracts - deployedContracts := 0 - contractAddresses := make([]common.Address, 0) - - // Check all transactions in the block - for _, tx := range block.Transactions() { - receipt, err := f.client.TransactionReceipt(runCtx, tx.Hash()) - require.NoError(f.t, err) - assert.Equal(f.t, uint64(1), receipt.Status) - - // If this is a contract creation transaction - if receipt.ContractAddress != (common.Address{}) { - deployedContracts++ - contractAddresses = append(contractAddresses, receipt.ContractAddress) - } - } - - // Verify the number of contracts deployed matches the expected count - assert.Equal(f.t, expectedContracts, deployedContracts, "Number of deployed contracts should match the scenario configuration") - - // Verify each contract's size - for _, addr := range contractAddresses { - code, err := f.client.CodeAt(runCtx, addr, nil) - require.NoError(f.t, err) - - // EIP-170 limit is 24,576 bytes (0x6000) - assert.Equal(f.t, 24576, len(code), "Contract code size should be exactly 24,576 bytes (EIP-170 limit)") - } - - f.logger.WithFields(logrus.Fields{ - "expected_contracts": expectedContracts, - "deployed_contracts": deployedContracts, - "contract_addresses": contractAddresses, - }).Info("Verified contract deployments") -} - -func TestContractDeployWithContractsPerBlock(t *testing.T) { - fixture := setupTestFixture(t) - defer fixture.teardown() - - // Initialize with contracts_per_block configuration - config := ` -max_pending: 0 -max_wallets: 1 -rebroadcast: 2 -base_fee: 20 -tip_fee: 2 -gas_per_block: 0 -client_group: default -contracts_per_block: 6 -max_transactions: 1 -` - require.NoError(t, fixture.scenario.Init(fixture.walletPool, config)) - - // Run scenario - runCtx, cancel := context.WithTimeout(fixture.ctx, 30*time.Second) - defer cancel() - - err := fixture.scenario.Run(runCtx) - require.NoError(t, err) - - fixture.verifyContractDeployment(runCtx) -} - -func TestContractDeployWithGasPerBlock(t *testing.T) { - fixture := setupTestFixture(t) - defer fixture.teardown() - - // Initialize with gas_per_block configuration - config := ` -max_pending: 0 -max_wallets: 1 -rebroadcast: 2 -base_fee: 20 -tip_fee: 2 -gas_per_block: 30000000 -client_group: default -contracts_per_block: 0 -max_transactions: 1 -` - require.NoError(t, fixture.scenario.Init(fixture.walletPool, config)) - - // Run scenario - runCtx, cancel := context.WithTimeout(fixture.ctx, 30*time.Second) - defer cancel() - - err := fixture.scenario.Run(runCtx) - require.NoError(t, err) - - fixture.verifyContractDeployment(runCtx) -} - -func TestContractDeployWithInvalidConfig(t *testing.T) { - fixture := setupTestFixture(t) - defer fixture.teardown() - - // Initialize with invalid configuration - config := ` -max_pending: 0 -max_wallets: 1 -rebroadcast: 1 -base_fee: 20 -tip_fee: 2 -gas_per_block: 0 -client_group: default -contracts_per_block: 0 -max_transactions: 1 -` - // We expect Init to fail with this configuration - err := fixture.scenario.Init(fixture.walletPool, config) - require.Error(t, err) - assert.Contains(t, err.Error(), "neither gas per block limit nor contracts per block set") -} From 2ab46fd94757ac59ab77c790cff3130285bc6d24 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sat, 24 May 2025 14:46:43 +0200 Subject: [PATCH 13/39] feat(contract-deploy): implement batch deployment strategy and transaction tracking - Introduced a batch deployment strategy that calculates the number of contracts fitting within the block gas limit. - Added detailed tracking for deployed contracts, including gas used and bytecode size, with structured loggin. - Improved nonce management and transaction retry logic. --- .../statebloat/contract_deploy/README.md | 54 +- .../contract_deploy/contract_deploy.go | 586 +++++++++++++----- 2 files changed, 478 insertions(+), 162 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/README.md b/scenarios/statebloat/contract_deploy/README.md index e6b70c0e..f0049958 100644 --- a/scenarios/statebloat/contract_deploy/README.md +++ b/scenarios/statebloat/contract_deploy/README.md @@ -6,7 +6,12 @@ This scenario deploys contracts that are exactly 24kB in size (EIP-170 limit) to 1. Generates a contract with exactly 24,576 bytes of runtime code 2. Deploys the contract using CREATE -3. Each deployment adds: +3. Uses batch-based deployment: + - Calculates how many contracts fit in one block based on gas limits + - Sends a batch of transactions that fit within the block gas limit + - Waits for a new block to be mined + - Repeats the process ("bombards" the RPC after each block) +4. Each deployment adds: - 24,576 bytes of runtime code - Account trie node - Total state growth: ~24.7kB per deployment @@ -18,6 +23,15 @@ This scenario deploys contracts that are exactly 24kB in size (EIP-170 limit) to - 200 gas per byte for code deposit (24,576 bytes) - Total: 4,967,200 gas per deployment +## Batch Strategy + +The scenario automatically calculates how many contracts can fit in one block: +- Default block gas limit: 30,000,000 gas +- Gas per contract: 4,967,200 gas +- Contracts per batch: ~6 contracts per block + +This ensures optimal utilization of block space while maintaining predictable transaction inclusion patterns. + ## Usage ```bash @@ -30,37 +44,40 @@ spamoor statebloat/contract-deploy [flags] - `--privkey` - Private key of the sending wallet - `--rpchost` - RPC endpoint(s) to send transactions to -#### Volume Control (either -c or -t required) -- `-c, --count` - Total number of contracts to deploy -- `-t, --throughput` - Contracts to deploy per slot +#### Volume Control +- `--max-transactions` - Maximum number of transactions to send (0 for unlimited) - `--max-pending` - Maximum number of pending deployments +- `--block-gas-limit` - Block gas limit for batching (default: 30,000,000, 0 = use default) #### Transaction Settings - `--basefee` - Max fee per gas in gwei (default: 20) - `--tipfee` - Max tip per gas in gwei (default: 2) -- `--rebroadcast` - Seconds to wait before rebroadcasting (default: 120) +- `--rebroadcast` - Seconds to wait before rebroadcasting (default: 1) #### Wallet Management - `--max-wallets` - Maximum number of child wallets to use -- `--refill-amount` - ETH amount to fund each child wallet (default: 5) -- `--refill-balance` - Minimum ETH balance before refilling (default: 2) -- `--refill-interval` - Seconds between balance checks (default: 300) +- `--client-group` - Client group to use for sending transactions (default: "default") -## Example +## Examples -Deploy 10 contracts: +Deploy 30 contracts in batches: ```bash -spamoor statebloat/contract-deploy -p "" -h http://localhost:8545 -c 10 +spamoor statebloat/contract-deploy \ + --privkey "" \ + --rpchost http://localhost:8545 \ + --max-transactions 30 ``` -Deploy 1 contract per slot: +Deploy with custom block gas limit (for testnets): ```bash -spamoor statebloat/contract-deploy -p "" -h http://localhost:8545 -t 1 +spamoor statebloat/contract-deploy \ + --privkey "" \ + --rpchost http://localhost:8545 \ + --max-transactions 10 \ + --block-gas-limit 15000000 ``` -## Running Against a Local Anvil Node (without Go tests) - -You can run this scenario directly against your own Anvil node using the Spamoor CLI, without running Go tests. +## Running Against a Local Anvil Node ### 1. Start Anvil @@ -82,16 +99,17 @@ go build -o spamoor ./cmd/spamoor ./spamoor statebloat/contract-deploy \ --privkey \ --rpchost http://localhost:8545 \ - --contracts-per-block 1 + --max-transactions 30 ``` - Replace `` with the private key of a funded account in your Anvil instance (Anvil prints these on startup). -- Adjust other flags as needed (`--contracts-per-block`, `--max-wallets`, etc.). +- The scenario will automatically calculate the optimal batch size based on gas limits. ### 4. Mining Notes - If you started Anvil with `--no-mining`, you will need to manually mine blocks (e.g., by calling `evm_mine` via RPC or using Anvil's console) to include the transactions. - If you use Anvil's default mining mode, blocks will be mined automatically as transactions are sent. +- The scenario waits for each block to be mined before sending the next batch, ensuring predictable transaction ordering. ### 5. See All Flags diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 0eb63a48..8525d613 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -2,11 +2,13 @@ package contractdeploy import ( "context" + "crypto/ecdsa" "crypto/rand" "encoding/json" "fmt" "math/big" "os" + "strings" "sync" "sync/atomic" "time" @@ -16,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/sirupsen/logrus" "github.com/spf13/pflag" @@ -28,6 +31,8 @@ import ( const ( // GAS_PER_CONTRACT is the estimated gas cost for deploying one StateBloatToken contract GAS_PER_CONTRACT = 4970000 // ~4.97M gas per contract + // BLOCK_GAS_LIMIT is the typical block gas limit for Ethereum mainnet + BLOCK_GAS_LIMIT = 30000000 // 30M gas ) type ScenarioOptions struct { @@ -38,6 +43,27 @@ type ScenarioOptions struct { TipFee uint64 `yaml:"tip_fee"` ClientGroup string `yaml:"client_group"` MaxTransactions uint64 `yaml:"max_transactions"` // Maximum number of transactions to send (0 for unlimited) + BlockGasLimit uint64 `yaml:"block_gas_limit"` // Block gas limit for batching (0 = use default) +} + +// ContractDeployment tracks a deployed contract with its deployer info +type ContractDeployment struct { + ContractAddress string `json:"contract_address"` + PrivateKey string `json:"private_key"` + TxHash string `json:"tx_hash"` + GasUsed uint64 `json:"gas_used"` + BlockNumber uint64 `json:"block_number"` + BytecodeSize int `json:"bytecode_size"` + GasPerByte string `json:"gas_per_byte"` +} + +// PendingTransaction tracks a transaction until it's mined +type PendingTransaction struct { + TxHash common.Hash + Wallet *txbuilder.Wallet + TxIndex uint64 + SentAt time.Time + PrivateKey *ecdsa.PrivateKey } type Scenario struct { @@ -45,22 +71,35 @@ type Scenario struct { logger *logrus.Entry walletPool *spamoor.WalletPool - pendingChan chan bool - pendingWGroup sync.WaitGroup + // Cached chain ID to avoid repeated RPC calls + chainID *big.Int + chainIDOnce sync.Once + chainIDError error + + // Transaction tracking + pendingTxs map[common.Hash]*PendingTransaction + pendingTxsMutex sync.RWMutex + maxConcurrent int - deployedAddresses []string - addressesMutex sync.Mutex + // Results tracking + deployedContracts []ContractDeployment + contractsMutex sync.Mutex + + // Nonce management per wallet + walletNonces map[common.Address]uint64 + nonceMutex sync.RWMutex } var ScenarioName = "contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ - MaxPending: 0, + MaxPending: 10, // Limit concurrent transactions MaxWallets: 0, Rebroadcast: 1, BaseFee: 20, TipFee: 2, ClientGroup: "default", MaxTransactions: 0, // Default to unlimited + BlockGasLimit: 0, // Use default BLOCK_GAS_LIMIT } var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ Name: ScenarioName, @@ -71,7 +110,10 @@ var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { return &Scenario{ - logger: logger.WithField("scenario", ScenarioName), + logger: logger.WithField("scenario", ScenarioName), + pendingTxs: make(map[common.Hash]*PendingTransaction), + walletNonces: make(map[common.Address]uint64), + maxConcurrent: 5, // Conservative default } } @@ -83,6 +125,7 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") flags.Uint64Var(&s.options.MaxTransactions, "max-transactions", ScenarioDefaultOptions.MaxTransactions, "Maximum number of transactions to send (0 for unlimited)") + flags.Uint64Var(&s.options.BlockGasLimit, "block-gas-limit", ScenarioDefaultOptions.BlockGasLimit, "Block gas limit for batching (0 = use default)") return nil } @@ -102,8 +145,9 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { walletPool.SetWalletCount(1000) } + // Set concurrent transaction limit if s.options.MaxPending > 0 { - s.pendingChan = make(chan bool, s.options.MaxPending) + s.maxConcurrent = int(s.options.MaxPending) } return nil @@ -114,210 +158,464 @@ func (s *Scenario) Config() string { return string(yamlBytes) } -func (s *Scenario) Run(ctx context.Context) error { - txIdxCounter := uint64(0) - pendingCount := atomic.Int64{} - txCount := atomic.Uint64{} - var lastChan chan bool +// getChainID caches the chain ID to avoid repeated RPC calls +func (s *Scenario) getChainID(ctx context.Context) (*big.Int, error) { + s.chainIDOnce.Do(func() { + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) + if client == nil { + s.chainIDError = fmt.Errorf("no client available for chain ID") + return + } + s.chainID, s.chainIDError = client.GetChainId(ctx) + if s.chainIDError == nil { + s.logger.Infof("Cached chain ID: %s", s.chainID.String()) + } + }) + return s.chainID, s.chainIDError +} - s.logger.Infof("starting scenario: %s", ScenarioName) - defer s.logger.Infof("scenario %s finished.", ScenarioName) +// getWalletNonce gets the current nonce for a wallet (without incrementing) +func (s *Scenario) getWalletNonce(ctx context.Context, wallet *txbuilder.Wallet, client *txbuilder.Client) (uint64, error) { + s.nonceMutex.Lock() + defer s.nonceMutex.Unlock() + + addr := crypto.PubkeyToAddress(wallet.GetPrivateKey().PublicKey) + + // Always refresh nonce from network to avoid gaps + nonce, err := client.GetEthClient().PendingNonceAt(ctx, addr) + if err != nil { + return 0, fmt.Errorf("failed to get nonce for %s: %w", addr.Hex(), err) + } + + // Store the current network nonce + s.walletNonces[addr] = nonce + s.logger.Debugf("Current nonce for wallet %s: %d", addr.Hex(), nonce) + + return nonce, nil +} + +// incrementWalletNonce increments the local nonce counter after successful tx send +func (s *Scenario) incrementWalletNonce(wallet *txbuilder.Wallet) { + s.nonceMutex.Lock() + defer s.nonceMutex.Unlock() + + addr := crypto.PubkeyToAddress(wallet.GetPrivateKey().PublicKey) + s.walletNonces[addr]++ + s.logger.Debugf("Incremented nonce for wallet %s to: %d", addr.Hex(), s.walletNonces[addr]) +} + +// waitForPendingTxSlot waits until we have capacity for another transaction +func (s *Scenario) waitForPendingTxSlot(ctx context.Context) { + for { + s.pendingTxsMutex.RLock() + count := len(s.pendingTxs) + s.pendingTxsMutex.RUnlock() + + if count < s.maxConcurrent { + return + } + + // Check and clean up confirmed transactions + s.processPendingTransactions(ctx) + time.Sleep(500 * time.Millisecond) + } +} + +// processPendingTransactions checks for transaction confirmations and updates state +func (s *Scenario) processPendingTransactions(ctx context.Context) { + s.pendingTxsMutex.Lock() + defer s.pendingTxsMutex.Unlock() client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) if client == nil { - return fmt.Errorf("no client available") + return } - var deployTxHashesMu sync.Mutex - var deployTxHashes []common.Hash + ethClient := client.GetEthClient() + var confirmedTxs []common.Hash - for { - if s.options.MaxTransactions > 0 && txIdxCounter >= s.options.MaxTransactions { - s.logger.Infof("reached maximum number of transactions (%d)", s.options.MaxTransactions) - break + for txHash, pendingTx := range s.pendingTxs { + receipt, err := ethClient.TransactionReceipt(ctx, txHash) + if err != nil { + // Transaction still pending or error retrieving receipt + continue } - txIdx := txIdxCounter - txIdxCounter++ + confirmedTxs = append(confirmedTxs, txHash) + + // Process successful deployment + if receipt.Status == 1 && receipt.ContractAddress != (common.Address{}) { + s.recordDeployedContract(receipt, pendingTx) + } else if receipt.Status != 1 { + s.logger.Warnf("Transaction failed: %s (gas used: %d)", txHash.Hex(), receipt.GasUsed) + } + } + + // Remove confirmed transactions from pending map + for _, txHash := range confirmedTxs { + delete(s.pendingTxs, txHash) + } + + if len(confirmedTxs) > 0 { + s.logger.Debugf("Processed %d confirmed transactions, %d still pending", + len(confirmedTxs), len(s.pendingTxs)) + } +} - if s.pendingChan != nil { - // await pending transactions - s.pendingChan <- true +// recordDeployedContract records a successfully deployed contract +func (s *Scenario) recordDeployedContract(receipt *types.Receipt, pendingTx *PendingTransaction) { + s.contractsMutex.Lock() + defer s.contractsMutex.Unlock() + + // Get the actual transaction to calculate real bytecode size + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) + var txBytes int + var gasPerByte float64 + + if client != nil { + tx, _, err := client.GetEthClient().TransactionByHash(context.Background(), receipt.TxHash) + if err == nil { + txBytes = len(tx.Data()) + gasPerByte = float64(receipt.GasUsed) / float64(max(txBytes, 1)) + } else { + // Fallback to estimated size + txBytes = 24564 // Approximate StateBloatToken bytecode size + gasPerByte = float64(receipt.GasUsed) / float64(txBytes) } - pendingCount.Add(1) - currentChan := make(chan bool, 1) - - go func(txIdx uint64, lastChan, currentChan chan bool) { - defer func() { - pendingCount.Add(-1) - currentChan <- true - }() - - logger := s.logger - tx, client, wallet, err := s.sendTx(ctx, txIdx, func() { - if s.pendingChan != nil { - time.Sleep(100 * time.Millisecond) - <-s.pendingChan - } - }) - if client != nil { - logger = logger.WithField("rpc", client.GetName()) - } - if tx != nil { - logger = logger.WithField("nonce", tx.Nonce()) - } - if wallet != nil { - logger = logger.WithField("wallet", s.walletPool.GetWalletName(wallet.GetAddress())) - } - if lastChan != nil { - <-lastChan - } - if err != nil { - logger.Warnf("could not send transaction: %v", err) - return - } - - // Collect tx hash for later receipt lookup - deployTxHashesMu.Lock() - deployTxHashes = append(deployTxHashes, tx.Hash()) - deployTxHashesMu.Unlock() - - txCount.Add(1) - }(txIdx, lastChan, currentChan) - - lastChan = currentChan - } - s.pendingWGroup.Wait() + } else { + // Fallback values + txBytes = 24564 + gasPerByte = float64(receipt.GasUsed) / float64(txBytes) + } + + deployment := ContractDeployment{ + ContractAddress: receipt.ContractAddress.Hex(), + PrivateKey: fmt.Sprintf("0x%x", crypto.FromECDSA(pendingTx.PrivateKey)), + TxHash: receipt.TxHash.Hex(), + GasUsed: receipt.GasUsed, + BlockNumber: receipt.BlockNumber.Uint64(), + BytecodeSize: txBytes, + GasPerByte: fmt.Sprintf("%.2f", gasPerByte), + } + + s.deployedContracts = append(s.deployedContracts, deployment) s.logger.WithFields(logrus.Fields{ - "test": "contract-deploy", - "total_txs": txCount.Load(), - "pending_txs": pendingCount.Load(), - }).Info("finished sending transactions, awaiting block inclusion...") + "contract_address": deployment.ContractAddress, + "tx_hash": deployment.TxHash, + "gas_used": deployment.GasUsed, + "block_number": deployment.BlockNumber, + "bytecode_size": deployment.BytecodeSize, + "gas_per_byte": deployment.GasPerByte, + "total_contracts": len(s.deployedContracts), + }).Info("Contract successfully deployed and recorded") +} - // Wait for a new block to be mined - ethClient := client.GetEthClient() - startBlock, err := ethClient.BlockByNumber(ctx, nil) +func (s *Scenario) Run(ctx context.Context) error { + s.logger.Infof("starting scenario: %s", ScenarioName) + defer s.logger.Infof("scenario %s finished.", ScenarioName) + + // Cache chain ID at startup + chainID, err := s.getChainID(ctx) if err != nil { - s.logger.Warnf("Failed to get current block: %v", err) - return err + return fmt.Errorf("failed to get chain ID: %w", err) } - startBlockNum := startBlock.NumberU64() - var latestBlockNum uint64 + + // Determine block gas limit to use + blockGasLimit := s.options.BlockGasLimit + if blockGasLimit == 0 { + blockGasLimit = BLOCK_GAS_LIMIT + } + + // Calculate how many contracts can fit in one block + contractsPerBlock := int(blockGasLimit / GAS_PER_CONTRACT) + if contractsPerBlock == 0 { + contractsPerBlock = 1 + } + + s.logger.Infof("Chain ID: %s, Block gas limit: %d, Gas per contract: %d, Contracts per block: %d, Max concurrent: %d", + chainID.String(), blockGasLimit, GAS_PER_CONTRACT, contractsPerBlock, s.maxConcurrent) + + txIdxCounter := uint64(0) + totalTxCount := atomic.Uint64{} + for { - block, err := ethClient.BlockByNumber(ctx, nil) - if err != nil { - s.logger.Warnf("Failed to get block: %v", err) - return err - } - latestBlockNum = block.NumberU64() - if latestBlockNum > startBlockNum { + // Check if we've reached max transactions + if s.options.MaxTransactions > 0 && txIdxCounter >= s.options.MaxTransactions { + s.logger.Infof("reached maximum number of transactions (%d)", s.options.MaxTransactions) break } - time.Sleep(2 * time.Second) - } - // For each deployment tx, get the receipt and log contract address and gas used - var deployedAddresses []string - for _, txHash := range deployTxHashes { - receipt, err := ethClient.TransactionReceipt(ctx, txHash) + // Wait for available slot + s.waitForPendingTxSlot(ctx) + + // Send a single transaction + err := s.sendTransaction(ctx, txIdxCounter) if err != nil { - s.logger.Warnf("Failed to get receipt for tx %s: %v", txHash.Hex(), err) + s.logger.Warnf("failed to send transaction %d: %v", txIdxCounter, err) + time.Sleep(1 * time.Second) continue } - if receipt.ContractAddress != (common.Address{}) { - addr := receipt.ContractAddress.Hex() - deployedAddresses = append(deployedAddresses, addr) - s.logger.Infof("Deployed contract at address: %s (gas used: %d)", addr, receipt.GasUsed) + + txIdxCounter++ + totalTxCount.Add(1) + + // Process pending transactions periodically + if txIdxCounter%10 == 0 { + s.processPendingTransactions(ctx) + + s.contractsMutex.Lock() + contractCount := len(s.deployedContracts) + s.contractsMutex.Unlock() + + s.logger.Infof("Progress: sent %d txs, deployed %d contracts", txIdxCounter, contractCount) + } + + // Small delay to prevent overwhelming the RPC + time.Sleep(100 * time.Millisecond) + } + + // Wait for all pending transactions to complete + s.logger.Info("Waiting for remaining transactions to complete...") + for { + s.processPendingTransactions(ctx) + + s.pendingTxsMutex.RLock() + pendingCount := len(s.pendingTxs) + s.pendingTxsMutex.RUnlock() + + if pendingCount == 0 { + break } + + s.logger.Infof("Waiting for %d pending transactions...", pendingCount) + time.Sleep(2 * time.Second) } - // Write deployed addresses to JSON file and log them - if len(deployedAddresses) > 0 { - file, err := os.Create("deployed_contracts.json") + // Save results to JSON + s.contractsMutex.Lock() + totalContracts := len(s.deployedContracts) + s.contractsMutex.Unlock() + + s.logger.WithFields(logrus.Fields{ + "test": "contract-deploy", + "total_txs": totalTxCount.Load(), + "total_contracts": totalContracts, + }).Info("All transactions completed") + + return s.saveDeployedContracts() +} + +// sendTransaction sends a single contract deployment transaction with retry logic +func (s *Scenario) sendTransaction(ctx context.Context, txIdx uint64) error { + maxRetries := 3 + baseGasMultiplier := 1.0 + + for attempt := 0; attempt < maxRetries; attempt++ { + err := s.attemptTransaction(ctx, txIdx, baseGasMultiplier) if err == nil { - _ = json.NewEncoder(file).Encode(deployedAddresses) - file.Close() - s.logger.Infof("Wrote %d deployed contract addresses to deployed_contracts.json", len(deployedAddresses)) - } else { - s.logger.Warnf("Failed to write deployed_contracts.json: %v", err) + return nil } - s.logger.Infof("Deployed contract addresses: %v", deployedAddresses) + + // Check if it's an underpriced error + if strings.Contains(err.Error(), "replacement transaction underpriced") || + strings.Contains(err.Error(), "transaction underpriced") { + baseGasMultiplier += 0.2 // Increase gas by 20% each retry + s.logger.Warnf("Transaction %d underpriced, retrying with %.1fx gas (attempt %d/%d)", + txIdx, baseGasMultiplier, attempt+1, maxRetries) + time.Sleep(time.Duration(attempt+1) * 500 * time.Millisecond) // Exponential backoff + continue + } + + // For other errors, return immediately + return err } - return nil + return fmt.Errorf("failed to send transaction after %d attempts", maxRetries) } -func (s *Scenario) sendTx(ctx context.Context, txIdx uint64, onComplete func()) (*types.Transaction, *txbuilder.Client, *txbuilder.Wallet, error) { - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, int(txIdx), s.options.ClientGroup) - wallet := s.walletPool.GetWallet(spamoor.SelectWalletByIndex, int(txIdx)) +// attemptTransaction makes a single attempt to send a transaction +func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, gasMultiplier float64) error { + // Get client and wallet + client := s.walletPool.GetClient(spamoor.SelectClientRoundRobin, 0, s.options.ClientGroup) + wallet := s.walletPool.GetWallet(spamoor.SelectWalletRoundRobin, 0) if client == nil { - return nil, nil, nil, fmt.Errorf("no client available") + return fmt.Errorf("no client available") } if wallet == nil { - return nil, nil, nil, fmt.Errorf("no wallet available") + return fmt.Errorf("no wallet available") } - // Get chain ID - chainId, err := client.GetChainId(ctx) + // Get cached chain ID + chainID, err := s.getChainID(ctx) if err != nil { - return nil, nil, nil, fmt.Errorf("failed to get chain ID: %w", err) + return fmt.Errorf("failed to get chain ID: %w", err) } - // Deploy contract - auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), chainId) + // Get current nonce for this wallet + nonce, err := s.getWalletNonce(ctx, wallet, client) if err != nil { - return nil, nil, nil, fmt.Errorf("failed to create auth: %w", err) + return fmt.Errorf("failed to get nonce: %w", err) } - auth.Nonce = big.NewInt(int64(wallet.GetNonce())) + // Create transaction auth + auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), chainID) + if err != nil { + return fmt.Errorf("failed to create auth: %w", err) + } + + auth.Nonce = big.NewInt(int64(nonce)) auth.Value = big.NewInt(0) - auth.GasLimit = GAS_PER_CONTRACT + GAS_PER_CONTRACT*5/100 // Gas for single contract deployment + auth.GasLimit = GAS_PER_CONTRACT + GAS_PER_CONTRACT*5/100 + + // Set EIP-1559 fee parameters with dynamic adjustment + baseFee := s.options.BaseFee + tipFee := s.options.TipFee + + if gasMultiplier > 1.0 { + baseFee = uint64(float64(baseFee) * gasMultiplier) + tipFee = uint64(float64(tipFee) * gasMultiplier) + } - // Set EIP-1559 fee parameters - if s.options.BaseFee > 0 { - auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) + if baseFee > 0 { + auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(baseFee)), big.NewInt(1000000000)) } - if s.options.TipFee > 0 { - auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) + if tipFee > 0 { + auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(tipFee)), big.NewInt(1000000000)) } // Generate random salt for unique contract salt := make([]byte, 32) _, err = rand.Read(salt) if err != nil { - return nil, nil, nil, fmt.Errorf("failed to generate salt: %w", err) + return fmt.Errorf("failed to generate salt: %w", err) } saltInt := new(big.Int).SetBytes(salt) - // Ensure we have a valid client + // Deploy the contract ethClient := client.GetEthClient() if ethClient == nil { - return nil, nil, nil, fmt.Errorf("failed to get eth client") + return fmt.Errorf("failed to get eth client") } - // Deploy the StateBloatToken contract address, tx, _, err := contract.DeployContract(auth, ethClient, saltInt) if err != nil { - return nil, nil, nil, fmt.Errorf("failed to deploy contract: %w", err) + return fmt.Errorf("failed to deploy contract: %w", err) } - // Update nonce - wallet.SetNonce(wallet.GetNonce() + 1) + // Track pending transaction + pendingTx := &PendingTransaction{ + TxHash: tx.Hash(), + Wallet: wallet, + TxIndex: txIdx, + SentAt: time.Now(), + PrivateKey: wallet.GetPrivateKey(), + } - // Calculate bytes written and gas/byte ratio - txBytes := len(tx.Data()) - gasPerByte := float64(GAS_PER_CONTRACT) / float64(txBytes) + s.pendingTxsMutex.Lock() + s.pendingTxs[tx.Hash()] = pendingTx + s.pendingTxsMutex.Unlock() s.logger.WithFields(logrus.Fields{ - "test": "contract-deploy", + "tx_index": txIdx, "tx_hash": tx.Hash().Hex(), - "contract_address": address.Hex(), - "bytes_written": txBytes, - "gas_per_byte": fmt.Sprintf("%.2f", gasPerByte), - "contracts": 1, - }).Info("deployed contract") + "expected_address": address.Hex(), + "nonce": nonce, + "wallet": crypto.PubkeyToAddress(wallet.GetPrivateKey().PublicKey).Hex(), + "gas_limit": auth.GasLimit, + "base_fee_gwei": baseFee, + "tip_fee_gwei": tipFee, + "gas_multiplier": fmt.Sprintf("%.1fx", gasMultiplier), + }).Info("Transaction sent successfully") + + // Only increment nonce after successful send + s.incrementWalletNonce(wallet) + + return nil +} + +// saveDeployedContracts saves the deployed contracts to JSON files +func (s *Scenario) saveDeployedContracts() error { + s.contractsMutex.Lock() + defer s.contractsMutex.Unlock() + + if len(s.deployedContracts) == 0 { + s.logger.Info("No contracts were deployed") + return nil + } + + // Save detailed contract info with private keys + contractsFile, err := os.Create("deployed_contracts_detailed.json") + if err != nil { + return fmt.Errorf("failed to create detailed contracts file: %w", err) + } + defer contractsFile.Close() + + err = json.NewEncoder(contractsFile).Encode(s.deployedContracts) + if err != nil { + return fmt.Errorf("failed to write detailed contracts: %w", err) + } + + // Save simple addresses list for compatibility + var addresses []string + for _, contract := range s.deployedContracts { + addresses = append(addresses, contract.ContractAddress) + } + + addressFile, err := os.Create("deployed_contracts.json") + if err != nil { + return fmt.Errorf("failed to create addresses file: %w", err) + } + defer addressFile.Close() + + err = json.NewEncoder(addressFile).Encode(addresses) + if err != nil { + return fmt.Errorf("failed to write addresses: %w", err) + } + + // Create contract-to-private-key mapping + contractKeyMap := make(map[string]string) + for _, contract := range s.deployedContracts { + contractKeyMap[contract.ContractAddress] = contract.PrivateKey + } + + keyMapFile, err := os.Create("contract_private_key_mapping.json") + if err != nil { + return fmt.Errorf("failed to create key mapping file: %w", err) + } + defer keyMapFile.Close() + + err = json.NewEncoder(keyMapFile).Encode(contractKeyMap) + if err != nil { + return fmt.Errorf("failed to write key mapping: %w", err) + } - return tx, client, wallet, nil + s.logger.WithFields(logrus.Fields{ + "contracts_deployed": len(s.deployedContracts), + "detailed_file": "deployed_contracts_detailed.json", + "addresses_file": "deployed_contracts.json", + "key_mapping_file": "contract_private_key_mapping.json", + }).Info("Successfully saved deployed contract information to JSON files") + + // Log summary of deployed contracts + var totalGasUsed uint64 + for _, contract := range s.deployedContracts { + totalGasUsed += contract.GasUsed + } + + s.logger.WithFields(logrus.Fields{ + "total_contracts": len(s.deployedContracts), + "total_gas_used": totalGasUsed, + "avg_gas_per_contract": totalGasUsed / uint64(len(s.deployedContracts)), + }).Info("Deployment summary") + + return nil +} + +func max(a, b int) int { + if a > b { + return a + } + return b } From 2c73f645efa01550713055eb27ba66c87532bd86 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sat, 24 May 2025 23:46:00 +0200 Subject: [PATCH 14/39] feat(contract-deploy): implement deployment mapping and final summary logging - Added functionality to save a mapping of private keys to contract addresses in a deployments.json file after each contract deployment. - Refactored the final summary logging to focus on the deployments.json file, removing the previous detailed contract saving logic. - imporved logging to provide insights into the total number of deployers and contracts processed. --- .../contract_deploy/contract_deploy.go | 106 ++++++++---------- 1 file changed, 48 insertions(+), 58 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 8525d613..478065ca 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -309,6 +309,47 @@ func (s *Scenario) recordDeployedContract(receipt *types.Receipt, pendingTx *Pen "gas_per_byte": deployment.GasPerByte, "total_contracts": len(s.deployedContracts), }).Info("Contract successfully deployed and recorded") + + // Save the deployments.json file each time a contract is confirmed + if err := s.saveDeploymentsMapping(); err != nil { + s.logger.Warnf("Failed to save deployments.json: %v", err) + } +} + +// saveDeploymentsMapping creates/updates deployments.json with private key to contract address mapping +func (s *Scenario) saveDeploymentsMapping() error { + // Create a map from private key to array of contract addresses + deploymentMap := make(map[string][]string) + + for _, contract := range s.deployedContracts { + privateKey := contract.PrivateKey + contractAddr := contract.ContractAddress + + deploymentMap[privateKey] = append(deploymentMap[privateKey], contractAddr) + } + + // Create or overwrite the deployments.json file + deploymentsFile, err := os.Create("deployments.json") + if err != nil { + return fmt.Errorf("failed to create deployments.json file: %w", err) + } + defer deploymentsFile.Close() + + // Write the mapping as JSON with pretty formatting + encoder := json.NewEncoder(deploymentsFile) + encoder.SetIndent("", " ") + err = encoder.Encode(deploymentMap) + if err != nil { + return fmt.Errorf("failed to write deployments.json: %w", err) + } + + s.logger.WithFields(logrus.Fields{ + "total_deployers": len(deploymentMap), + "total_contracts": len(s.deployedContracts), + "file": "deployments.json", + }).Info("Updated deployments mapping file") + + return nil } func (s *Scenario) Run(ctx context.Context) error { @@ -403,7 +444,8 @@ func (s *Scenario) Run(ctx context.Context) error { "total_contracts": totalContracts, }).Info("All transactions completed") - return s.saveDeployedContracts() + // Log final summary + return s.logFinalSummary() } // sendTransaction sends a single contract deployment transaction with retry logic @@ -535,8 +577,8 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, gasMult return nil } -// saveDeployedContracts saves the deployed contracts to JSON files -func (s *Scenario) saveDeployedContracts() error { +// logFinalSummary logs the final summary of the scenario +func (s *Scenario) logFinalSummary() error { s.contractsMutex.Lock() defer s.contractsMutex.Unlock() @@ -545,60 +587,7 @@ func (s *Scenario) saveDeployedContracts() error { return nil } - // Save detailed contract info with private keys - contractsFile, err := os.Create("deployed_contracts_detailed.json") - if err != nil { - return fmt.Errorf("failed to create detailed contracts file: %w", err) - } - defer contractsFile.Close() - - err = json.NewEncoder(contractsFile).Encode(s.deployedContracts) - if err != nil { - return fmt.Errorf("failed to write detailed contracts: %w", err) - } - - // Save simple addresses list for compatibility - var addresses []string - for _, contract := range s.deployedContracts { - addresses = append(addresses, contract.ContractAddress) - } - - addressFile, err := os.Create("deployed_contracts.json") - if err != nil { - return fmt.Errorf("failed to create addresses file: %w", err) - } - defer addressFile.Close() - - err = json.NewEncoder(addressFile).Encode(addresses) - if err != nil { - return fmt.Errorf("failed to write addresses: %w", err) - } - - // Create contract-to-private-key mapping - contractKeyMap := make(map[string]string) - for _, contract := range s.deployedContracts { - contractKeyMap[contract.ContractAddress] = contract.PrivateKey - } - - keyMapFile, err := os.Create("contract_private_key_mapping.json") - if err != nil { - return fmt.Errorf("failed to create key mapping file: %w", err) - } - defer keyMapFile.Close() - - err = json.NewEncoder(keyMapFile).Encode(contractKeyMap) - if err != nil { - return fmt.Errorf("failed to write key mapping: %w", err) - } - - s.logger.WithFields(logrus.Fields{ - "contracts_deployed": len(s.deployedContracts), - "detailed_file": "deployed_contracts_detailed.json", - "addresses_file": "deployed_contracts.json", - "key_mapping_file": "contract_private_key_mapping.json", - }).Info("Successfully saved deployed contract information to JSON files") - - // Log summary of deployed contracts + // Log final summary var totalGasUsed uint64 for _, contract := range s.deployedContracts { totalGasUsed += contract.GasUsed @@ -608,7 +597,8 @@ func (s *Scenario) saveDeployedContracts() error { "total_contracts": len(s.deployedContracts), "total_gas_used": totalGasUsed, "avg_gas_per_contract": totalGasUsed / uint64(len(s.deployedContracts)), - }).Info("Deployment summary") + "deployments_file": "deployments.json", + }).Info("Final deployment summary - only deployments.json file created") return nil } From bdf65289b9e1912b831b7a0efe22b27ff41164cc Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sun, 25 May 2025 00:12:34 +0200 Subject: [PATCH 15/39] refactor(contract-deploy): streamline contract deployment logic and improve transaction handling - Removed unused imports and redundant fields. - Simplified transaction processing by releasing locks earlier. - Improved logging for transaction sending and contract deployment confirmation. - Cleaned up nonce management by directly fetching the nonce from the client. --- .../contract_deploy/contract_deploy.go | 281 +++--------------- 1 file changed, 44 insertions(+), 237 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 478065ca..5fe42591 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -8,7 +8,6 @@ import ( "fmt" "math/big" "os" - "strings" "sync" "sync/atomic" "time" @@ -17,7 +16,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/sirupsen/logrus" "github.com/spf13/pflag" @@ -25,44 +23,26 @@ import ( "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy/contract" "github.com/ethpandaops/spamoor/scenariotypes" "github.com/ethpandaops/spamoor/spamoor" - "github.com/ethpandaops/spamoor/txbuilder" -) - -const ( - // GAS_PER_CONTRACT is the estimated gas cost for deploying one StateBloatToken contract - GAS_PER_CONTRACT = 4970000 // ~4.97M gas per contract - // BLOCK_GAS_LIMIT is the typical block gas limit for Ethereum mainnet - BLOCK_GAS_LIMIT = 30000000 // 30M gas ) type ScenarioOptions struct { MaxPending uint64 `yaml:"max_pending"` MaxWallets uint64 `yaml:"max_wallets"` - Rebroadcast uint64 `yaml:"rebroadcast"` BaseFee uint64 `yaml:"base_fee"` TipFee uint64 `yaml:"tip_fee"` ClientGroup string `yaml:"client_group"` - MaxTransactions uint64 `yaml:"max_transactions"` // Maximum number of transactions to send (0 for unlimited) - BlockGasLimit uint64 `yaml:"block_gas_limit"` // Block gas limit for batching (0 = use default) + MaxTransactions uint64 `yaml:"max_transactions"` } // ContractDeployment tracks a deployed contract with its deployer info type ContractDeployment struct { ContractAddress string `json:"contract_address"` PrivateKey string `json:"private_key"` - TxHash string `json:"tx_hash"` - GasUsed uint64 `json:"gas_used"` - BlockNumber uint64 `json:"block_number"` - BytecodeSize int `json:"bytecode_size"` - GasPerByte string `json:"gas_per_byte"` } // PendingTransaction tracks a transaction until it's mined type PendingTransaction struct { TxHash common.Hash - Wallet *txbuilder.Wallet - TxIndex uint64 - SentAt time.Time PrivateKey *ecdsa.PrivateKey } @@ -79,27 +59,20 @@ type Scenario struct { // Transaction tracking pendingTxs map[common.Hash]*PendingTransaction pendingTxsMutex sync.RWMutex - maxConcurrent int // Results tracking deployedContracts []ContractDeployment contractsMutex sync.Mutex - - // Nonce management per wallet - walletNonces map[common.Address]uint64 - nonceMutex sync.RWMutex } var ScenarioName = "contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ - MaxPending: 10, // Limit concurrent transactions + MaxPending: 10, MaxWallets: 0, - Rebroadcast: 1, BaseFee: 20, TipFee: 2, ClientGroup: "default", - MaxTransactions: 0, // Default to unlimited - BlockGasLimit: 0, // Use default BLOCK_GAS_LIMIT + MaxTransactions: 0, } var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ Name: ScenarioName, @@ -110,22 +83,18 @@ var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { return &Scenario{ - logger: logger.WithField("scenario", ScenarioName), - pendingTxs: make(map[common.Hash]*PendingTransaction), - walletNonces: make(map[common.Address]uint64), - maxConcurrent: 5, // Conservative default + logger: logger.WithField("scenario", ScenarioName), + pendingTxs: make(map[common.Hash]*PendingTransaction), } } func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.MaxPending, "max-pending", ScenarioDefaultOptions.MaxPending, "Maximum number of pending transactions") flags.Uint64Var(&s.options.MaxWallets, "max-wallets", ScenarioDefaultOptions.MaxWallets, "Maximum number of child wallets to use") - flags.Uint64Var(&s.options.Rebroadcast, "rebroadcast", ScenarioDefaultOptions.Rebroadcast, "Number of seconds to wait before re-broadcasting a transaction") flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Max fee per gas to use in transactions (in gwei)") flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") flags.Uint64Var(&s.options.MaxTransactions, "max-transactions", ScenarioDefaultOptions.MaxTransactions, "Maximum number of transactions to send (0 for unlimited)") - flags.Uint64Var(&s.options.BlockGasLimit, "block-gas-limit", ScenarioDefaultOptions.BlockGasLimit, "Block gas limit for batching (0 = use default)") return nil } @@ -145,11 +114,6 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { walletPool.SetWalletCount(1000) } - // Set concurrent transaction limit - if s.options.MaxPending > 0 { - s.maxConcurrent = int(s.options.MaxPending) - } - return nil } @@ -167,43 +131,10 @@ func (s *Scenario) getChainID(ctx context.Context) (*big.Int, error) { return } s.chainID, s.chainIDError = client.GetChainId(ctx) - if s.chainIDError == nil { - s.logger.Infof("Cached chain ID: %s", s.chainID.String()) - } }) return s.chainID, s.chainIDError } -// getWalletNonce gets the current nonce for a wallet (without incrementing) -func (s *Scenario) getWalletNonce(ctx context.Context, wallet *txbuilder.Wallet, client *txbuilder.Client) (uint64, error) { - s.nonceMutex.Lock() - defer s.nonceMutex.Unlock() - - addr := crypto.PubkeyToAddress(wallet.GetPrivateKey().PublicKey) - - // Always refresh nonce from network to avoid gaps - nonce, err := client.GetEthClient().PendingNonceAt(ctx, addr) - if err != nil { - return 0, fmt.Errorf("failed to get nonce for %s: %w", addr.Hex(), err) - } - - // Store the current network nonce - s.walletNonces[addr] = nonce - s.logger.Debugf("Current nonce for wallet %s: %d", addr.Hex(), nonce) - - return nonce, nil -} - -// incrementWalletNonce increments the local nonce counter after successful tx send -func (s *Scenario) incrementWalletNonce(wallet *txbuilder.Wallet) { - s.nonceMutex.Lock() - defer s.nonceMutex.Unlock() - - addr := crypto.PubkeyToAddress(wallet.GetPrivateKey().PublicKey) - s.walletNonces[addr]++ - s.logger.Debugf("Incremented nonce for wallet %s to: %d", addr.Hex(), s.walletNonces[addr]) -} - // waitForPendingTxSlot waits until we have capacity for another transaction func (s *Scenario) waitForPendingTxSlot(ctx context.Context) { for { @@ -211,7 +142,7 @@ func (s *Scenario) waitForPendingTxSlot(ctx context.Context) { count := len(s.pendingTxs) s.pendingTxsMutex.RUnlock() - if count < s.maxConcurrent { + if count < int(s.options.MaxPending) { return } @@ -224,15 +155,19 @@ func (s *Scenario) waitForPendingTxSlot(ctx context.Context) { // processPendingTransactions checks for transaction confirmations and updates state func (s *Scenario) processPendingTransactions(ctx context.Context) { s.pendingTxsMutex.Lock() - defer s.pendingTxsMutex.Unlock() client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) if client == nil { + s.pendingTxsMutex.Unlock() return } ethClient := client.GetEthClient() var confirmedTxs []common.Hash + var successfulDeployments []struct { + ContractAddress common.Address + PrivateKey *ecdsa.PrivateKey + } for txHash, pendingTx := range s.pendingTxs { receipt, err := ethClient.TransactionReceipt(ctx, txHash) @@ -245,9 +180,13 @@ func (s *Scenario) processPendingTransactions(ctx context.Context) { // Process successful deployment if receipt.Status == 1 && receipt.ContractAddress != (common.Address{}) { - s.recordDeployedContract(receipt, pendingTx) - } else if receipt.Status != 1 { - s.logger.Warnf("Transaction failed: %s (gas used: %d)", txHash.Hex(), receipt.GasUsed) + successfulDeployments = append(successfulDeployments, struct { + ContractAddress common.Address + PrivateKey *ecdsa.PrivateKey + }{ + ContractAddress: receipt.ContractAddress, + PrivateKey: pendingTx.PrivateKey, + }) } } @@ -256,59 +195,30 @@ func (s *Scenario) processPendingTransactions(ctx context.Context) { delete(s.pendingTxs, txHash) } - if len(confirmedTxs) > 0 { - s.logger.Debugf("Processed %d confirmed transactions, %d still pending", - len(confirmedTxs), len(s.pendingTxs)) + s.pendingTxsMutex.Unlock() + + // Process successful deployments after releasing the lock + for _, deployment := range successfulDeployments { + s.recordDeployedContract(deployment.ContractAddress, deployment.PrivateKey) } } // recordDeployedContract records a successfully deployed contract -func (s *Scenario) recordDeployedContract(receipt *types.Receipt, pendingTx *PendingTransaction) { +func (s *Scenario) recordDeployedContract(contractAddress common.Address, privateKey *ecdsa.PrivateKey) { s.contractsMutex.Lock() defer s.contractsMutex.Unlock() - // Get the actual transaction to calculate real bytecode size - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) - var txBytes int - var gasPerByte float64 - - if client != nil { - tx, _, err := client.GetEthClient().TransactionByHash(context.Background(), receipt.TxHash) - if err == nil { - txBytes = len(tx.Data()) - gasPerByte = float64(receipt.GasUsed) / float64(max(txBytes, 1)) - } else { - // Fallback to estimated size - txBytes = 24564 // Approximate StateBloatToken bytecode size - gasPerByte = float64(receipt.GasUsed) / float64(txBytes) - } - } else { - // Fallback values - txBytes = 24564 - gasPerByte = float64(receipt.GasUsed) / float64(txBytes) - } - deployment := ContractDeployment{ - ContractAddress: receipt.ContractAddress.Hex(), - PrivateKey: fmt.Sprintf("0x%x", crypto.FromECDSA(pendingTx.PrivateKey)), - TxHash: receipt.TxHash.Hex(), - GasUsed: receipt.GasUsed, - BlockNumber: receipt.BlockNumber.Uint64(), - BytecodeSize: txBytes, - GasPerByte: fmt.Sprintf("%.2f", gasPerByte), + ContractAddress: contractAddress.Hex(), + PrivateKey: fmt.Sprintf("0x%x", crypto.FromECDSA(privateKey)), } s.deployedContracts = append(s.deployedContracts, deployment) s.logger.WithFields(logrus.Fields{ "contract_address": deployment.ContractAddress, - "tx_hash": deployment.TxHash, - "gas_used": deployment.GasUsed, - "block_number": deployment.BlockNumber, - "bytecode_size": deployment.BytecodeSize, - "gas_per_byte": deployment.GasPerByte, "total_contracts": len(s.deployedContracts), - }).Info("Contract successfully deployed and recorded") + }).Info("Contract deployed") // Save the deployments.json file each time a contract is confirmed if err := s.saveDeploymentsMapping(); err != nil { @@ -324,7 +234,6 @@ func (s *Scenario) saveDeploymentsMapping() error { for _, contract := range s.deployedContracts { privateKey := contract.PrivateKey contractAddr := contract.ContractAddress - deploymentMap[privateKey] = append(deploymentMap[privateKey], contractAddr) } @@ -343,12 +252,6 @@ func (s *Scenario) saveDeploymentsMapping() error { return fmt.Errorf("failed to write deployments.json: %w", err) } - s.logger.WithFields(logrus.Fields{ - "total_deployers": len(deploymentMap), - "total_contracts": len(s.deployedContracts), - "file": "deployments.json", - }).Info("Updated deployments mapping file") - return nil } @@ -362,20 +265,7 @@ func (s *Scenario) Run(ctx context.Context) error { return fmt.Errorf("failed to get chain ID: %w", err) } - // Determine block gas limit to use - blockGasLimit := s.options.BlockGasLimit - if blockGasLimit == 0 { - blockGasLimit = BLOCK_GAS_LIMIT - } - - // Calculate how many contracts can fit in one block - contractsPerBlock := int(blockGasLimit / GAS_PER_CONTRACT) - if contractsPerBlock == 0 { - contractsPerBlock = 1 - } - - s.logger.Infof("Chain ID: %s, Block gas limit: %d, Gas per contract: %d, Contracts per block: %d, Max concurrent: %d", - chainID.String(), blockGasLimit, GAS_PER_CONTRACT, contractsPerBlock, s.maxConcurrent) + s.logger.Infof("Chain ID: %s", chainID.String()) txIdxCounter := uint64(0) totalTxCount := atomic.Uint64{} @@ -433,51 +323,21 @@ func (s *Scenario) Run(ctx context.Context) error { time.Sleep(2 * time.Second) } - // Save results to JSON + // Log final summary s.contractsMutex.Lock() totalContracts := len(s.deployedContracts) s.contractsMutex.Unlock() s.logger.WithFields(logrus.Fields{ - "test": "contract-deploy", "total_txs": totalTxCount.Load(), "total_contracts": totalContracts, }).Info("All transactions completed") - // Log final summary - return s.logFinalSummary() + return nil } -// sendTransaction sends a single contract deployment transaction with retry logic +// sendTransaction sends a single contract deployment transaction func (s *Scenario) sendTransaction(ctx context.Context, txIdx uint64) error { - maxRetries := 3 - baseGasMultiplier := 1.0 - - for attempt := 0; attempt < maxRetries; attempt++ { - err := s.attemptTransaction(ctx, txIdx, baseGasMultiplier) - if err == nil { - return nil - } - - // Check if it's an underpriced error - if strings.Contains(err.Error(), "replacement transaction underpriced") || - strings.Contains(err.Error(), "transaction underpriced") { - baseGasMultiplier += 0.2 // Increase gas by 20% each retry - s.logger.Warnf("Transaction %d underpriced, retrying with %.1fx gas (attempt %d/%d)", - txIdx, baseGasMultiplier, attempt+1, maxRetries) - time.Sleep(time.Duration(attempt+1) * 500 * time.Millisecond) // Exponential backoff - continue - } - - // For other errors, return immediately - return err - } - - return fmt.Errorf("failed to send transaction after %d attempts", maxRetries) -} - -// attemptTransaction makes a single attempt to send a transaction -func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, gasMultiplier float64) error { // Get client and wallet client := s.walletPool.GetClient(spamoor.SelectClientRoundRobin, 0, s.options.ClientGroup) wallet := s.walletPool.GetWallet(spamoor.SelectWalletRoundRobin, 0) @@ -496,9 +356,10 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, gasMult } // Get current nonce for this wallet - nonce, err := s.getWalletNonce(ctx, wallet, client) + addr := crypto.PubkeyToAddress(wallet.GetPrivateKey().PublicKey) + nonce, err := client.GetEthClient().PendingNonceAt(ctx, addr) if err != nil { - return fmt.Errorf("failed to get nonce: %w", err) + return fmt.Errorf("failed to get nonce for %s: %w", addr.Hex(), err) } // Create transaction auth @@ -509,22 +370,14 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, gasMult auth.Nonce = big.NewInt(int64(nonce)) auth.Value = big.NewInt(0) - auth.GasLimit = GAS_PER_CONTRACT + GAS_PER_CONTRACT*5/100 - - // Set EIP-1559 fee parameters with dynamic adjustment - baseFee := s.options.BaseFee - tipFee := s.options.TipFee - - if gasMultiplier > 1.0 { - baseFee = uint64(float64(baseFee) * gasMultiplier) - tipFee = uint64(float64(tipFee) * gasMultiplier) - } + auth.GasLimit = 5200000 // Fixed gas limit for contract deployment - if baseFee > 0 { - auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(baseFee)), big.NewInt(1000000000)) + // Set EIP-1559 fee parameters + if s.options.BaseFee > 0 { + auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) } - if tipFee > 0 { - auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(tipFee)), big.NewInt(1000000000)) + if s.options.TipFee > 0 { + auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) } // Generate random salt for unique contract @@ -541,7 +394,7 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, gasMult return fmt.Errorf("failed to get eth client") } - address, tx, _, err := contract.DeployContract(auth, ethClient, saltInt) + _, tx, _, err := contract.DeployContract(auth, ethClient, saltInt) if err != nil { return fmt.Errorf("failed to deploy contract: %w", err) } @@ -549,9 +402,6 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, gasMult // Track pending transaction pendingTx := &PendingTransaction{ TxHash: tx.Hash(), - Wallet: wallet, - TxIndex: txIdx, - SentAt: time.Now(), PrivateKey: wallet.GetPrivateKey(), } @@ -560,52 +410,9 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, gasMult s.pendingTxsMutex.Unlock() s.logger.WithFields(logrus.Fields{ - "tx_index": txIdx, - "tx_hash": tx.Hash().Hex(), - "expected_address": address.Hex(), - "nonce": nonce, - "wallet": crypto.PubkeyToAddress(wallet.GetPrivateKey().PublicKey).Hex(), - "gas_limit": auth.GasLimit, - "base_fee_gwei": baseFee, - "tip_fee_gwei": tipFee, - "gas_multiplier": fmt.Sprintf("%.1fx", gasMultiplier), - }).Info("Transaction sent successfully") - - // Only increment nonce after successful send - s.incrementWalletNonce(wallet) + "tx_hash": tx.Hash().Hex(), + "nonce": nonce, + }).Info("Transaction sent") return nil } - -// logFinalSummary logs the final summary of the scenario -func (s *Scenario) logFinalSummary() error { - s.contractsMutex.Lock() - defer s.contractsMutex.Unlock() - - if len(s.deployedContracts) == 0 { - s.logger.Info("No contracts were deployed") - return nil - } - - // Log final summary - var totalGasUsed uint64 - for _, contract := range s.deployedContracts { - totalGasUsed += contract.GasUsed - } - - s.logger.WithFields(logrus.Fields{ - "total_contracts": len(s.deployedContracts), - "total_gas_used": totalGasUsed, - "avg_gas_per_contract": totalGasUsed / uint64(len(s.deployedContracts)), - "deployments_file": "deployments.json", - }).Info("Final deployment summary - only deployments.json file created") - - return nil -} - -func max(a, b int) int { - if a > b { - return a - } - return b -} From bdbaa836400e47872ad31e63ff3c43383e25375e Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sun, 25 May 2025 23:05:32 +0200 Subject: [PATCH 16/39] feat(contract-deploy): enhance transaction handling and dynamic fee adjustment - Added functionality to dynamically adjust transaction fees based on current network conditions. - Implemented retry logic for transaction sending with exponential backoff for base fee errors. --- .../contract_deploy/contract_deploy.go | 131 +++++++++++++++++- 1 file changed, 126 insertions(+), 5 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 5fe42591..cc7e80af 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -8,6 +8,7 @@ import ( "fmt" "math/big" "os" + "strings" "sync" "sync/atomic" "time" @@ -20,6 +21,7 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/pflag" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy/contract" "github.com/ethpandaops/spamoor/scenariotypes" "github.com/ethpandaops/spamoor/spamoor" @@ -167,6 +169,8 @@ func (s *Scenario) processPendingTransactions(ctx context.Context) { var successfulDeployments []struct { ContractAddress common.Address PrivateKey *ecdsa.PrivateKey + Receipt *types.Receipt + TxHash common.Hash } for txHash, pendingTx := range s.pendingTxs { @@ -183,9 +187,13 @@ func (s *Scenario) processPendingTransactions(ctx context.Context) { successfulDeployments = append(successfulDeployments, struct { ContractAddress common.Address PrivateKey *ecdsa.PrivateKey + Receipt *types.Receipt + TxHash common.Hash }{ ContractAddress: receipt.ContractAddress, PrivateKey: pendingTx.PrivateKey, + Receipt: receipt, + TxHash: txHash, }) } } @@ -199,15 +207,16 @@ func (s *Scenario) processPendingTransactions(ctx context.Context) { // Process successful deployments after releasing the lock for _, deployment := range successfulDeployments { - s.recordDeployedContract(deployment.ContractAddress, deployment.PrivateKey) + s.recordDeployedContract(deployment.ContractAddress, deployment.PrivateKey, deployment.Receipt, deployment.TxHash) } } // recordDeployedContract records a successfully deployed contract -func (s *Scenario) recordDeployedContract(contractAddress common.Address, privateKey *ecdsa.PrivateKey) { +func (s *Scenario) recordDeployedContract(contractAddress common.Address, privateKey *ecdsa.PrivateKey, receipt *types.Receipt, txHash common.Hash) { s.contractsMutex.Lock() defer s.contractsMutex.Unlock() + // Keep the JSON structure simple - only contract address and private key deployment := ContractDeployment{ ContractAddress: contractAddress.Hex(), PrivateKey: fmt.Sprintf("0x%x", crypto.FromECDSA(privateKey)), @@ -215,10 +224,35 @@ func (s *Scenario) recordDeployedContract(contractAddress common.Address, privat s.deployedContracts = append(s.deployedContracts, deployment) + // Calculate detailed information for logging + walletAddress := crypto.PubkeyToAddress(privateKey.PublicKey) + + // Get the actual transaction to calculate real bytecode size + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) + var bytecodeSize int = 24564 // Default fallback + var gasPerByte float64 + + if client != nil { + tx, _, err := client.GetEthClient().TransactionByHash(context.Background(), txHash) + if err == nil { + bytecodeSize = len(tx.Data()) + } + } + + // Calculate gas per byte + gasPerByte = float64(receipt.GasUsed) / float64(max(bytecodeSize, 1)) + + // Log with detailed information s.logger.WithFields(logrus.Fields{ + "block_number": receipt.BlockNumber.Uint64(), + "bytecode_size": bytecodeSize, "contract_address": deployment.ContractAddress, + "gas_per_byte": fmt.Sprintf("%.2f", gasPerByte), + "gas_used": receipt.GasUsed, "total_contracts": len(s.deployedContracts), - }).Info("Contract deployed") + "tx_hash": txHash.Hex(), + "wallet_address": walletAddress.Hex(), + }).Info("Contract successfully deployed and recorded") // Save the deployments.json file each time a contract is confirmed if err := s.saveDeploymentsMapping(); err != nil { @@ -226,6 +260,14 @@ func (s *Scenario) recordDeployedContract(contractAddress common.Address, privat } } +// Helper function for max calculation +func max(a, b int) int { + if a > b { + return a + } + return b +} + // saveDeploymentsMapping creates/updates deployments.json with private key to contract address mapping func (s *Scenario) saveDeploymentsMapping() error { // Create a map from private key to array of contract addresses @@ -338,6 +380,82 @@ func (s *Scenario) Run(ctx context.Context) error { // sendTransaction sends a single contract deployment transaction func (s *Scenario) sendTransaction(ctx context.Context, txIdx uint64) error { + maxRetries := 3 + + for attempt := 0; attempt < maxRetries; attempt++ { + err := s.attemptTransaction(ctx, txIdx, attempt) + if err == nil { + return nil + } + + // Check if it's a base fee error + if strings.Contains(err.Error(), "max fee per gas less than block base fee") { + s.logger.Warnf("Transaction %d base fee too low, adjusting fees and retrying (attempt %d/%d)", + txIdx, attempt+1, maxRetries) + + // Update fees based on current network conditions + if updateErr := s.updateDynamicFees(ctx); updateErr != nil { + s.logger.Warnf("Failed to update dynamic fees: %v", updateErr) + } + + time.Sleep(time.Duration(attempt+1) * 500 * time.Millisecond) // Exponential backoff + continue + } + + // For other errors, return immediately + return err + } + + return fmt.Errorf("failed to send transaction after %d attempts", maxRetries) +} + +// updateDynamicFees queries the network and updates base fee and tip fee +func (s *Scenario) updateDynamicFees(ctx context.Context) error { + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) + if client == nil { + return fmt.Errorf("no client available") + } + + ethClient := client.GetEthClient() + + // Get the latest block to check current base fee + latestBlock, err := ethClient.BlockByNumber(ctx, nil) + if err != nil { + return fmt.Errorf("failed to get latest block: %w", err) + } + + if latestBlock.BaseFee() != nil { + // Convert base fee from wei to gwei + currentBaseFeeGwei := new(big.Int).Div(latestBlock.BaseFee(), big.NewInt(1000000000)) + + // Set new base fee to current base fee + 20% buffer + newBaseFeeGwei := new(big.Int).Mul(currentBaseFeeGwei, big.NewInt(120)) + newBaseFeeGwei = new(big.Int).Div(newBaseFeeGwei, big.NewInt(100)) + + // Ensure minimum increase of 5 gwei + minIncrease := big.NewInt(5) + if newBaseFeeGwei.Cmp(new(big.Int).Add(big.NewInt(int64(s.options.BaseFee)), minIncrease)) < 0 { + newBaseFeeGwei = new(big.Int).Add(big.NewInt(int64(s.options.BaseFee)), minIncrease) + } + + s.options.BaseFee = newBaseFeeGwei.Uint64() + + // Also increase tip fee slightly to ensure competitive priority + if s.options.TipFee+1 > 3 { + s.options.TipFee = s.options.TipFee + 1 + } else { + s.options.TipFee = 3 // Minimum 3 gwei tip + } + + s.logger.Infof("Updated dynamic fees - Base fee: %d gwei, Tip fee: %d gwei (network base fee: %s gwei)", + s.options.BaseFee, s.options.TipFee, currentBaseFeeGwei.String()) + } + + return nil +} + +// attemptTransaction makes a single attempt to send a transaction +func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, attempt int) error { // Get client and wallet client := s.walletPool.GetClient(spamoor.SelectClientRoundRobin, 0, s.options.ClientGroup) wallet := s.walletPool.GetWallet(spamoor.SelectWalletRoundRobin, 0) @@ -410,8 +528,11 @@ func (s *Scenario) sendTransaction(ctx context.Context, txIdx uint64) error { s.pendingTxsMutex.Unlock() s.logger.WithFields(logrus.Fields{ - "tx_hash": tx.Hash().Hex(), - "nonce": nonce, + "tx_hash": tx.Hash().Hex(), + "nonce": nonce, + "base_fee_gwei": s.options.BaseFee, + "tip_fee_gwei": s.options.TipFee, + "attempt": attempt + 1, }).Info("Transaction sent") return nil From 82138080f71dee7402ee694734d691543112974f Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sun, 25 May 2025 23:18:19 +0200 Subject: [PATCH 17/39] chore: update readme --- scenarios/statebloat/contract_deploy/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/README.md b/scenarios/statebloat/contract_deploy/README.md index f0049958..dd839c48 100644 --- a/scenarios/statebloat/contract_deploy/README.md +++ b/scenarios/statebloat/contract_deploy/README.md @@ -5,7 +5,7 @@ This scenario deploys contracts that are exactly 24kB in size (EIP-170 limit) to ## How it Works 1. Generates a contract with exactly 24,576 bytes of runtime code -2. Deploys the contract using CREATE +2. Deploys the contract using CREATE with a salt that makes the bytecode unique. 3. Uses batch-based deployment: - Calculates how many contracts fit in one block based on gas limits - Sends a batch of transactions that fit within the block gas limit @@ -82,7 +82,7 @@ spamoor statebloat/contract-deploy \ ### 1. Start Anvil ```bash -anvil --hardfork pectra +anvil --hardfork latest --block-time 12 ``` You can add other flags as needed (e.g., `--no-mining` if you want to control mining manually). From 891a0b4cd00161de15e7cf5be866af6434a41b50 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 26 May 2025 00:17:16 +0200 Subject: [PATCH 18/39] chore: Clarify running instructions in contract_deploy readme --- .../statebloat/contract_deploy/README.md | 97 ++++--------------- 1 file changed, 19 insertions(+), 78 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/README.md b/scenarios/statebloat/contract_deploy/README.md index dd839c48..204e3dfe 100644 --- a/scenarios/statebloat/contract_deploy/README.md +++ b/scenarios/statebloat/contract_deploy/README.md @@ -1,11 +1,11 @@ -# Contract Deployment State Bloat +# 🏭 Contract Deployment State Bloat This scenario deploys contracts that are exactly 24kB in size (EIP-170 limit) to maximize state growth while minimizing gas cost. ## How it Works 1. Generates a contract with exactly 24,576 bytes of runtime code -2. Deploys the contract using CREATE with a salt that makes the bytecode unique. +2. Deploys the contract using CREATE with a salt that makes the bytecode unique 3. Uses batch-based deployment: - Calculates how many contracts fit in one block based on gas limits - Sends a batch of transactions that fit within the block gas limit @@ -16,12 +16,12 @@ This scenario deploys contracts that are exactly 24kB in size (EIP-170 limit) to - Account trie node - Total state growth: ~24.7kB per deployment -## Gas Cost Breakdown +## ⛽ Gas Cost Breakdown - 32,000 gas for CREATE - 20,000 gas for new account - 200 gas per byte for code deposit (24,576 bytes) -- Total: 4,967,200 gas per deployment +- **Total: 4,967,200 gas per deployment** ## Batch Strategy @@ -32,87 +32,28 @@ The scenario automatically calculates how many contracts can fit in one block: This ensures optimal utilization of block space while maintaining predictable transaction inclusion patterns. -## Usage +## 🚀 Usage +### Build ```bash -spamoor statebloat/contract-deploy [flags] +go build -o bin/spamoor cmd/spamoor/main.go ``` -### Configuration - -#### Base Settings (required) -- `--privkey` - Private key of the sending wallet -- `--rpchost` - RPC endpoint(s) to send transactions to - -#### Volume Control -- `--max-transactions` - Maximum number of transactions to send (0 for unlimited) -- `--max-pending` - Maximum number of pending deployments -- `--block-gas-limit` - Block gas limit for batching (default: 30,000,000, 0 = use default) - -#### Transaction Settings -- `--basefee` - Max fee per gas in gwei (default: 20) -- `--tipfee` - Max tip per gas in gwei (default: 2) -- `--rebroadcast` - Seconds to wait before rebroadcasting (default: 1) - -#### Wallet Management -- `--max-wallets` - Maximum number of child wallets to use -- `--client-group` - Client group to use for sending transactions (default: "default") - -## Examples - -Deploy 30 contracts in batches: -```bash -spamoor statebloat/contract-deploy \ - --privkey "" \ - --rpchost http://localhost:8545 \ - --max-transactions 30 -``` - -Deploy with custom block gas limit (for testnets): -```bash -spamoor statebloat/contract-deploy \ - --privkey "" \ - --rpchost http://localhost:8545 \ - --max-transactions 10 \ - --block-gas-limit 15000000 -``` - -## Running Against a Local Anvil Node - -### 1. Start Anvil - +### Run ```bash -anvil --hardfork latest --block-time 12 +./bin/spamoor --privkey --rpchost http://localhost:8545 contract-deploy [flags] ``` -You can add other flags as needed (e.g., `--no-mining` if you want to control mining manually). - -### 2. Build Spamoor (if not already built) - -```bash -go build -o spamoor ./cmd/spamoor -``` - -### 3. Run the Scenario - -```bash -./spamoor statebloat/contract-deploy \ - --privkey \ - --rpchost http://localhost:8545 \ - --max-transactions 30 -``` - -- Replace `` with the private key of a funded account in your Anvil instance (Anvil prints these on startup). -- The scenario will automatically calculate the optimal batch size based on gas limits. - -### 4. Mining Notes - -- If you started Anvil with `--no-mining`, you will need to manually mine blocks (e.g., by calling `evm_mine` via RPC or using Anvil's console) to include the transactions. -- If you use Anvil's default mining mode, blocks will be mined automatically as transactions are sent. -- The scenario waits for each block to be mined before sending the next batch, ensuring predictable transaction ordering. - -### 5. See All Flags +#### Key Flags +- `--max-transactions` - Number of contracts to deploy (0 = infinite, default: 0) +- `--max-pending` - Max concurrent pending transactions (default: 10) +- `--max-wallets` - Max child wallets to use (default: 1000) +- `--basefee` - Base fee per gas in gwei (default: 20) +- `--tipfee` - Tip fee per gas in gwei (default: 2) +#### Example with Anvil node ```bash -./spamoor statebloat/contract-deploy --help +./bin/spamoor --privkey ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + --rpchost http://localhost:8545 contract-deploy \ + --max-transactions 100 --max-pending 20 --basefee 25 --tipfee 5 ``` \ No newline at end of file From c2d431369be84a015d76312cbb90e986278499af Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 4 Jun 2025 12:51:34 +0200 Subject: [PATCH 19/39] update: Contract bytecode reduction to account for extra costs --- .../contract/StateBloatToken.abi | 2 +- .../contract/StateBloatToken.bin | 2 +- .../contract/StateBloatToken.go | 314 +----------------- .../contract/StateBloatToken.sol | 40 --- 4 files changed, 4 insertions(+), 354 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi index 4dea8206..0f67a8f3 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi @@ -1 +1 @@ -[{"inputs":[{"internalType":"uint256","name":"_salt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dummy1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy10","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy11","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy12","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy13","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy14","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy15","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy16","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy17","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy19","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy21","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy22","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy23","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy24","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy25","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy26","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy27","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy28","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy29","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy30","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy31","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy32","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy33","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy34","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy35","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy36","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy37","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy38","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy39","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy4","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy40","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy41","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy42","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy43","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy44","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy45","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy46","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy47","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy48","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy49","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy5","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy50","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy51","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy52","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy53","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy54","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy55","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy56","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy57","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy58","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy59","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy6","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy60","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy61","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy62","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy63","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy64","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy65","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy66","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy67","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy68","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy69","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy7","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy70","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy71","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy72","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy73","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy74","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy75","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy8","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy9","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom1","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom10","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom11","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom12","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom13","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom14","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom15","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom16","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom17","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom18","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom19","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom2","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom3","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom4","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom5","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom6","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom7","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom8","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom9","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"inputs":[{"internalType":"uint256","name":"_salt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dummy1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy10","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy11","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy12","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy13","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy14","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy15","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy16","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy17","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy19","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy21","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy22","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy23","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy24","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy25","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy26","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy27","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy28","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy29","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy30","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy31","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy32","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy33","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy34","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy35","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy36","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy37","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy38","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy39","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy4","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy40","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy41","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy42","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy43","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy44","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy45","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy46","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy47","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy48","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy49","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy5","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy50","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy51","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy52","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy53","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy54","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy55","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy56","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy57","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy58","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy59","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy6","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy60","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy61","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy62","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy63","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy64","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy65","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy7","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy8","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy9","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom1","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom10","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom11","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom12","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom13","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom14","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom15","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom16","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom17","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom18","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom19","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom2","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom3","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom4","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom5","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom6","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom7","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom8","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom9","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin index 10e9b41a..7d363997 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin @@ -1 +1 @@ -60a060405234801561000f575f5ffd5b50604051615fd4380380615fd4833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b60805161587f6107555f395f614a7b015261587f5ff3fe608060405234801561000f575f5ffd5b5060043610610606575f3560e01c8063657b6ef711610319578063b1802b9a116101a6578063d9bb3174116100f2578063f26c779b116100ab578063f8716f1411610085578063f8716f1414611360578063faf35ced1461137e578063fe7d5996146113ae578063ffbf0469146113cc57610606565b8063f26c779b14611306578063f4978b0414611324578063f5f573811461134257610606565b8063d9bb31741461122e578063dc1d8a9b1461124c578063dd62ed3e1461126a578063e2d275301461129a578063e8c927b3146112b8578063eb4329c8146112d657610606565b8063bbe231321161015f578063c958d4bf11610139578063c958d4bf146111b6578063cfd66863146111d4578063d101dcd0146111f2578063d74194691461121057610606565b8063bbe231321461114a578063bfa0b13314611168578063c2be97e31461118657610606565b8063b1802b9a14611072578063b2bb360e146110a2578063b4c48668146110c0578063b66dd750146110de578063b9a6d645146110fc578063bb9bfe061461111a57610606565b80637e544937116102655780639c5dfe731161021e578063a9059cbb116101f8578063a9059cbb14610fd6578063aaa7af7014611006578063acc5aee914611024578063ad8f42211461105457610606565b80639c5dfe7314610f7c5780639df61a2514610f9a578063a891d4d414610fb857610606565b80637e54493714610eb65780637f34d94b14610ed45780638619d60714610ef25780638789ca6714610f105780638f4a840614610f4057806395d89b4114610f5e57610606565b806374f83d02116102d25780637a319c18116102ac5780637a319c1814610e2c5780637c66673e14610e4a5780637c72ed0d14610e7a5780637dffdc3214610e9857610606565b806374f83d0214610dd257806377c0209e14610df0578063792c7f3e14610e0e57610606565b8063657b6ef714610ce8578063672151fe14610d185780636abceacd14610d365780636c12ed2814610d5457806370a0823114610d8457806374e73fd314610db457610606565b8063313ce567116104975780634b3c7f5f116103e357806358b6a9bd1161039c57806361b970eb1161037657806361b970eb14610c70578063639ec53a14610c8e5780636547317414610cac5780636578534c14610cca57610606565b806358b6a9bd14610c16578063595471b814610c345780635af92c0514610c5257610606565b80634b3c7f5f14610b3e5780634e1dbb8214610b5c5780634f5e555714610b7a5780634f7bd75a14610b9857806354c2792014610bc8578063552a1b5614610be657610606565b80633ea117ce1161045057806342937dbd1161042a57806342937dbd14610ab457806343a6b92d14610ad257806344050a2814610af05780634a2e93c614610b2057610606565b80633ea117ce14610a5a5780634128a85d14610a78578063418b181614610a9657610606565b8063313ce5671461098257806334517f0b146109a0578063378c5382146109be57806339e0bd12146109dc5780633a13199014610a0c5780633b6be45914610a3c57610606565b80631bbffe6f1161055657806321ecd7a31161050f5780632545d8b7116104e95780632545d8b7146108f85780632787325b14610916578063291c3bd7146109345780633125f37a1461096457610606565b806321ecd7a31461088c578063239af2a5146108aa57806323b872dd146108c857610606565b80631bbffe6f146107c65780631d527cde146107f65780631eaa7c52146108145780631f29783f146108325780631f449589146108505780631fd298ec1461086e57610606565b806312901b42116105c357806318160ddd1161059d57806318160ddd1461073c57806319cf6a911461075a5780631a97f18e146107785780631b17c65c1461079657610606565b806312901b42146106e257806313ebb5ec1461070057806316a3045b1461071e57610606565b80630460faf61461060a57806306fdde031461063a5780630717b16114610658578063095ea7b3146106765780630cb7a9e7146106a65780631215a3ab146106c4575b5f5ffd5b610624600480360381019061061f91906153a3565b6113ea565b604051610631919061540d565b60405180910390f35b6106426116ca565b60405161064f9190615496565b60405180910390f35b610660611755565b60405161066d91906154c5565b60405180910390f35b610690600480360381019061068b91906154de565b61175d565b60405161069d919061540d565b60405180910390f35b6106ae61184a565b6040516106bb91906154c5565b60405180910390f35b6106cc611852565b6040516106d991906154c5565b60405180910390f35b6106ea61185a565b6040516106f791906154c5565b60405180910390f35b610708611862565b60405161071591906154c5565b60405180910390f35b61072661186a565b60405161073391906154c5565b60405180910390f35b610744611872565b60405161075191906154c5565b60405180910390f35b610762611878565b60405161076f91906154c5565b60405180910390f35b610780611880565b60405161078d91906154c5565b60405180910390f35b6107b060048036038101906107ab91906153a3565b611888565b6040516107bd919061540d565b60405180910390f35b6107e060048036038101906107db91906153a3565b611b68565b6040516107ed919061540d565b60405180910390f35b6107fe611e48565b60405161080b91906154c5565b60405180910390f35b61081c611e50565b60405161082991906154c5565b60405180910390f35b61083a611e58565b60405161084791906154c5565b60405180910390f35b610858611e60565b60405161086591906154c5565b60405180910390f35b610876611e68565b60405161088391906154c5565b60405180910390f35b610894611e70565b6040516108a191906154c5565b60405180910390f35b6108b2611e78565b6040516108bf91906154c5565b60405180910390f35b6108e260048036038101906108dd91906153a3565b611e80565b6040516108ef919061540d565b60405180910390f35b610900612160565b60405161090d91906154c5565b60405180910390f35b61091e612168565b60405161092b91906154c5565b60405180910390f35b61094e600480360381019061094991906153a3565b612170565b60405161095b919061540d565b60405180910390f35b61096c612450565b60405161097991906154c5565b60405180910390f35b61098a612458565b6040516109979190615537565b60405180910390f35b6109a861246a565b6040516109b591906154c5565b60405180910390f35b6109c6612472565b6040516109d391906154c5565b60405180910390f35b6109f660048036038101906109f191906153a3565b61247a565b604051610a03919061540d565b60405180910390f35b610a266004803603810190610a2191906153a3565b61275a565b604051610a33919061540d565b60405180910390f35b610a44612a3a565b604051610a5191906154c5565b60405180910390f35b610a62612a42565b604051610a6f91906154c5565b60405180910390f35b610a80612a4a565b604051610a8d91906154c5565b60405180910390f35b610a9e612a52565b604051610aab91906154c5565b60405180910390f35b610abc612a5a565b604051610ac991906154c5565b60405180910390f35b610ada612a62565b604051610ae791906154c5565b60405180910390f35b610b0a6004803603810190610b0591906153a3565b612a6a565b604051610b17919061540d565b60405180910390f35b610b28612d4a565b604051610b3591906154c5565b60405180910390f35b610b46612d52565b604051610b5391906154c5565b60405180910390f35b610b64612d5a565b604051610b7191906154c5565b60405180910390f35b610b82612d62565b604051610b8f91906154c5565b60405180910390f35b610bb26004803603810190610bad91906153a3565b612d6a565b604051610bbf919061540d565b60405180910390f35b610bd061304a565b604051610bdd91906154c5565b60405180910390f35b610c006004803603810190610bfb91906153a3565b613052565b604051610c0d919061540d565b60405180910390f35b610c1e613332565b604051610c2b91906154c5565b60405180910390f35b610c3c61333a565b604051610c4991906154c5565b60405180910390f35b610c5a613342565b604051610c6791906154c5565b60405180910390f35b610c7861334a565b604051610c8591906154c5565b60405180910390f35b610c96613352565b604051610ca391906154c5565b60405180910390f35b610cb461335a565b604051610cc191906154c5565b60405180910390f35b610cd2613362565b604051610cdf91906154c5565b60405180910390f35b610d026004803603810190610cfd91906153a3565b61336a565b604051610d0f919061540d565b60405180910390f35b610d2061364a565b604051610d2d91906154c5565b60405180910390f35b610d3e613652565b604051610d4b91906154c5565b60405180910390f35b610d6e6004803603810190610d6991906153a3565b61365a565b604051610d7b919061540d565b60405180910390f35b610d9e6004803603810190610d999190615550565b61393a565b604051610dab91906154c5565b60405180910390f35b610dbc61394f565b604051610dc991906154c5565b60405180910390f35b610dda613957565b604051610de791906154c5565b60405180910390f35b610df861395f565b604051610e0591906154c5565b60405180910390f35b610e16613967565b604051610e2391906154c5565b60405180910390f35b610e3461396f565b604051610e4191906154c5565b60405180910390f35b610e646004803603810190610e5f91906153a3565b613977565b604051610e71919061540d565b60405180910390f35b610e82613c57565b604051610e8f91906154c5565b60405180910390f35b610ea0613c5f565b604051610ead91906154c5565b60405180910390f35b610ebe613c67565b604051610ecb91906154c5565b60405180910390f35b610edc613c6f565b604051610ee991906154c5565b60405180910390f35b610efa613c77565b604051610f0791906154c5565b60405180910390f35b610f2a6004803603810190610f2591906153a3565b613c7f565b604051610f37919061540d565b60405180910390f35b610f48613f5f565b604051610f5591906154c5565b60405180910390f35b610f66613f67565b604051610f739190615496565b60405180910390f35b610f84613ff3565b604051610f9191906154c5565b60405180910390f35b610fa2613ffb565b604051610faf91906154c5565b60405180910390f35b610fc0614003565b604051610fcd91906154c5565b60405180910390f35b610ff06004803603810190610feb91906154de565b61400b565b604051610ffd919061540d565b60405180910390f35b61100e6141a1565b60405161101b91906154c5565b60405180910390f35b61103e600480360381019061103991906153a3565b6141a9565b60405161104b919061540d565b60405180910390f35b61105c614489565b60405161106991906154c5565b60405180910390f35b61108c600480360381019061108791906153a3565b614491565b604051611099919061540d565b60405180910390f35b6110aa614771565b6040516110b791906154c5565b60405180910390f35b6110c8614779565b6040516110d591906154c5565b60405180910390f35b6110e6614781565b6040516110f391906154c5565b60405180910390f35b611104614789565b60405161111191906154c5565b60405180910390f35b611134600480360381019061112f91906153a3565b614791565b604051611141919061540d565b60405180910390f35b611152614a71565b60405161115f91906154c5565b60405180910390f35b611170614a79565b60405161117d91906154c5565b60405180910390f35b6111a0600480360381019061119b91906153a3565b614a9d565b6040516111ad919061540d565b60405180910390f35b6111be614d7d565b6040516111cb91906154c5565b60405180910390f35b6111dc614d85565b6040516111e991906154c5565b60405180910390f35b6111fa614d8d565b60405161120791906154c5565b60405180910390f35b611218614d95565b60405161122591906154c5565b60405180910390f35b611236614d9d565b60405161124391906154c5565b60405180910390f35b611254614da5565b60405161126191906154c5565b60405180910390f35b611284600480360381019061127f919061557b565b614dad565b60405161129191906154c5565b60405180910390f35b6112a2614dcd565b6040516112af91906154c5565b60405180910390f35b6112c0614dd5565b6040516112cd91906154c5565b60405180910390f35b6112f060048036038101906112eb91906153a3565b614ddd565b6040516112fd919061540d565b60405180910390f35b61130e615002565b60405161131b91906154c5565b60405180910390f35b61132c61500a565b60405161133991906154c5565b60405180910390f35b61134a615012565b60405161135791906154c5565b60405180910390f35b61136861501a565b60405161137591906154c5565b60405180910390f35b611398600480360381019061139391906153a3565b615022565b6040516113a5919061540d565b60405180910390f35b6113b6615302565b6040516113c391906154c5565b60405180910390f35b6113d461530a565b6040516113e191906154c5565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561146b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461157291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546115c591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461165391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516116b791906154c5565b60405180910390a3600190509392505050565b5f80546116d690615749565b80601f016020809104026020016040519081016040528092919081815260200182805461170290615749565b801561174d5780601f106117245761010080835404028352916020019161174d565b820191905f5260205f20905b81548152906001019060200180831161173057829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161183891906154c5565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190090615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156119c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bb9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611a1091906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611a6391906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611af191906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611b5591906154c5565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9b9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611cf091906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611d4391906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611dd191906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611e3591906154c5565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6048905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb39061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461200891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461205b91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546120e991906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161214d91906154c5565b60405180910390a3600190509392505050565b5f6001905090565b5f6045905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156121f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e8906157c3565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156122ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a39061582b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546122f891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461234b91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546123d991906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161243d91906154c5565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f604b905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156124fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156125b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ad9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461260291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461265591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546126e391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161274791906154c5565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156127db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546128e291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461293591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546129c391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612a2791906154c5565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612aeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ba6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612bf291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612c4591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612cd391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612d3791906154c5565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612de290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ea6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ef291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612f4591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612fd391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161303791906154c5565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156130d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ca90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561318e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131859061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546131da91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461322d91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546132bb91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161331f91906154c5565b60405180910390a3600190509392505050565b5f6009905090565b5f6049905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f6043905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156133eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133e2906157c3565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156134a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349d9061582b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546134f291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461354591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135d391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161363791906154c5565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156136db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136d290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161378d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546137e291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461383591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546138c391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161392791906154c5565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156139f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139ef90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613ab3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613aaa9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613aff91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613b5291906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613be091906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613c4491906154c5565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613d00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613cf790615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613db29061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e0791906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e5a91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ee891906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613f4c91906154c5565b60405180910390a3600190509392505050565b5f600b905090565b60018054613f7490615749565b80601f0160208091040260200160405190810160405280929190818152602001828054613fa090615749565b8015613feb5780601f10613fc257610100808354040283529160200191613feb565b820191905f5260205f20905b815481529060010190602001808311613fce57829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561408c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161408390615603565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546140d891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461412b91906156e9565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161418f91906154c5565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561422a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161422190615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156142e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016142dc9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461433191906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461438491906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461441291906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161447691906154c5565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161450990615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156145cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016145c49061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461461991906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461466c91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146fa91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161475e91906154c5565b60405180910390a3600190509392505050565b5f6018905090565b5f604a905090565b5f600f905090565b5f6044905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161480990615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156148cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148c49061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461491991906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461496c91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546149fa91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614a5e91906154c5565b60405180910390a3600190509392505050565b5f6046905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614b1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614b1590615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614bd09061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c2591906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c7891906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d0691906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614d6a91906154c5565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6042905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614e55906157c3565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614eaa91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614efd91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f8b91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614fef91906154c5565b60405180910390a3600190509392505050565b5f6007905090565b5f6047905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156150a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161509a90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561515e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016151559061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546151aa91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546151fd91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461528b91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516152ef91906154c5565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61533f82615316565b9050919050565b61534f81615335565b8114615359575f5ffd5b50565b5f8135905061536a81615346565b92915050565b5f819050919050565b61538281615370565b811461538c575f5ffd5b50565b5f8135905061539d81615379565b92915050565b5f5f5f606084860312156153ba576153b9615312565b5b5f6153c78682870161535c565b93505060206153d88682870161535c565b92505060406153e98682870161538f565b9150509250925092565b5f8115159050919050565b615407816153f3565b82525050565b5f6020820190506154205f8301846153fe565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61546882615426565b6154728185615430565b9350615482818560208601615440565b61548b8161544e565b840191505092915050565b5f6020820190508181035f8301526154ae818461545e565b905092915050565b6154bf81615370565b82525050565b5f6020820190506154d85f8301846154b6565b92915050565b5f5f604083850312156154f4576154f3615312565b5b5f6155018582860161535c565b92505060206155128582860161538f565b9150509250929050565b5f60ff82169050919050565b6155318161551c565b82525050565b5f60208201905061554a5f830184615528565b92915050565b5f6020828403121561556557615564615312565b5b5f6155728482850161535c565b91505092915050565b5f5f6040838503121561559157615590615312565b5b5f61559e8582860161535c565b92505060206155af8582860161535c565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6155ed601483615430565b91506155f8826155b9565b602082019050919050565b5f6020820190508181035f83015261561a816155e1565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f615655601683615430565b915061566082615621565b602082019050919050565b5f6020820190508181035f83015261568281615649565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6156c082615370565b91506156cb83615370565b92508282039050818111156156e3576156e2615689565b5b92915050565b5f6156f382615370565b91506156fe83615370565b925082820190508082111561571657615715615689565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061576057607f821691505b6020821081036157735761577261571c565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6157ad600183615430565b91506157b882615779565b602082019050919050565b5f6020820190508181035f8301526157da816157a1565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f615815600183615430565b9150615820826157e1565b602082019050919050565b5f6020820190508181035f83015261584281615809565b905091905056fea2646970667358221220ce03f2ea0f8ec341a07b9c0512b41f44d879b740c55b3572c5707216663e8a3f64736f6c634300081e0033 \ No newline at end of file +60a060405234801561000f575f5ffd5b50604051615d6a380380615d6a833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b6080516156156107555f395f61482101526156155ff3fe608060405234801561000f575f5ffd5b5060043610610518575f3560e01c8063657b6ef7116102a2578063aaa7af7011610170578063d7419469116100d7578063f26c779b11610090578063f26c779b1461110a578063f5f5738114611128578063f8716f1414611146578063faf35ced14611164578063fe7d599614611194578063ffbf0469146111b257610518565b8063d741946914611032578063dc1d8a9b14611050578063dd62ed3e1461106e578063e2d275301461109e578063e8c927b3146110bc578063eb4329c8146110da57610518565b8063bb9bfe0611610129578063bb9bfe0614610f5a578063bfa0b13314610f8a578063c2be97e314610fa8578063c958d4bf14610fd8578063cfd6686314610ff6578063d101dcd01461101457610518565b8063aaa7af7014610e82578063acc5aee914610ea0578063ad8f422114610ed0578063b1802b9a14610eee578063b2bb360e14610f1e578063b66dd75014610f3c57610518565b80637c72ed0d116102145780638f4a8406116101cd5780638f4a840614610dbc57806395d89b4114610dda5780639c5dfe7314610df85780639df61a2514610e16578063a891d4d414610e34578063a9059cbb14610e5257610518565b80637c72ed0d14610cf65780637dffdc3214610d145780637e54493714610d325780637f34d94b14610d505780638619d60714610d6e5780638789ca6714610d8c57610518565b806374e73fd31161026657806374e73fd314610c3057806374f83d0214610c4e57806377c0209e14610c6c578063792c7f3e14610c8a5780637a319c1814610ca85780637c66673e14610cc657610518565b8063657b6ef714610b64578063672151fe14610b945780636abceacd14610bb25780636c12ed2814610bd057806370a0823114610c0057610518565b80633125f37a116103ea5780634a2e93c611610351578063552a1b561161030a578063552a1b5614610a9e57806358b6a9bd14610ace5780635af92c0514610aec57806361b970eb14610b0a578063639ec53a14610b285780636547317414610b4657610518565b80634a2e93c6146109d85780634b3c7f5f146109f65780634e1dbb8214610a145780634f5e555714610a325780634f7bd75a14610a5057806354c2792014610a8057610518565b80633ea117ce116103a35780633ea117ce146109125780634128a85d14610930578063418b18161461094e57806342937dbd1461096c57806343a6b92d1461098a57806344050a28146109a857610518565b80633125f37a1461083a578063313ce5671461085857806334517f0b1461087657806339e0bd12146108945780633a131990146108c45780633b6be459146108f457610518565b80631a97f18e1161048e5780631fd298ec116104475780631fd298ec1461076257806321ecd7a314610780578063239af2a51461079e57806323b872dd146107bc5780632545d8b7146107ec578063291c3bd71461080a57610518565b80631a97f18e1461068a5780631b17c65c146106a85780631bbffe6f146106d85780631d527cde146107085780631eaa7c52146107265780631f4495891461074457610518565b80631215a3ab116104e05780631215a3ab146105d657806312901b42146105f457806313ebb5ec1461061257806316a3045b1461063057806318160ddd1461064e57806319cf6a911461066c57610518565b80630460faf61461051c57806306fdde031461054c5780630717b1611461056a578063095ea7b3146105885780630cb7a9e7146105b8575b5f5ffd5b61053660048036038101906105319190615139565b6111d0565b60405161054391906151a3565b60405180910390f35b6105546114b0565b604051610561919061522c565b60405180910390f35b61057261153b565b60405161057f919061525b565b60405180910390f35b6105a2600480360381019061059d9190615274565b611543565b6040516105af91906151a3565b60405180910390f35b6105c0611630565b6040516105cd919061525b565b60405180910390f35b6105de611638565b6040516105eb919061525b565b60405180910390f35b6105fc611640565b604051610609919061525b565b60405180910390f35b61061a611648565b604051610627919061525b565b60405180910390f35b610638611650565b604051610645919061525b565b60405180910390f35b610656611658565b604051610663919061525b565b60405180910390f35b61067461165e565b604051610681919061525b565b60405180910390f35b610692611666565b60405161069f919061525b565b60405180910390f35b6106c260048036038101906106bd9190615139565b61166e565b6040516106cf91906151a3565b60405180910390f35b6106f260048036038101906106ed9190615139565b61194e565b6040516106ff91906151a3565b60405180910390f35b610710611c2e565b60405161071d919061525b565b60405180910390f35b61072e611c36565b60405161073b919061525b565b60405180910390f35b61074c611c3e565b604051610759919061525b565b60405180910390f35b61076a611c46565b604051610777919061525b565b60405180910390f35b610788611c4e565b604051610795919061525b565b60405180910390f35b6107a6611c56565b6040516107b3919061525b565b60405180910390f35b6107d660048036038101906107d19190615139565b611c5e565b6040516107e391906151a3565b60405180910390f35b6107f4611f3e565b604051610801919061525b565b60405180910390f35b610824600480360381019061081f9190615139565b611f46565b60405161083191906151a3565b60405180910390f35b610842612226565b60405161084f919061525b565b60405180910390f35b61086061222e565b60405161086d91906152cd565b60405180910390f35b61087e612240565b60405161088b919061525b565b60405180910390f35b6108ae60048036038101906108a99190615139565b612248565b6040516108bb91906151a3565b60405180910390f35b6108de60048036038101906108d99190615139565b612528565b6040516108eb91906151a3565b60405180910390f35b6108fc612808565b604051610909919061525b565b60405180910390f35b61091a612810565b604051610927919061525b565b60405180910390f35b610938612818565b604051610945919061525b565b60405180910390f35b610956612820565b604051610963919061525b565b60405180910390f35b610974612828565b604051610981919061525b565b60405180910390f35b610992612830565b60405161099f919061525b565b60405180910390f35b6109c260048036038101906109bd9190615139565b612838565b6040516109cf91906151a3565b60405180910390f35b6109e0612b18565b6040516109ed919061525b565b60405180910390f35b6109fe612b20565b604051610a0b919061525b565b60405180910390f35b610a1c612b28565b604051610a29919061525b565b60405180910390f35b610a3a612b30565b604051610a47919061525b565b60405180910390f35b610a6a6004803603810190610a659190615139565b612b38565b604051610a7791906151a3565b60405180910390f35b610a88612e18565b604051610a95919061525b565b60405180910390f35b610ab86004803603810190610ab39190615139565b612e20565b604051610ac591906151a3565b60405180910390f35b610ad6613100565b604051610ae3919061525b565b60405180910390f35b610af4613108565b604051610b01919061525b565b60405180910390f35b610b12613110565b604051610b1f919061525b565b60405180910390f35b610b30613118565b604051610b3d919061525b565b60405180910390f35b610b4e613120565b604051610b5b919061525b565b60405180910390f35b610b7e6004803603810190610b799190615139565b613128565b604051610b8b91906151a3565b60405180910390f35b610b9c613408565b604051610ba9919061525b565b60405180910390f35b610bba613410565b604051610bc7919061525b565b60405180910390f35b610bea6004803603810190610be59190615139565b613418565b604051610bf791906151a3565b60405180910390f35b610c1a6004803603810190610c1591906152e6565b6136f8565b604051610c27919061525b565b60405180910390f35b610c3861370d565b604051610c45919061525b565b60405180910390f35b610c56613715565b604051610c63919061525b565b60405180910390f35b610c7461371d565b604051610c81919061525b565b60405180910390f35b610c92613725565b604051610c9f919061525b565b60405180910390f35b610cb061372d565b604051610cbd919061525b565b60405180910390f35b610ce06004803603810190610cdb9190615139565b613735565b604051610ced91906151a3565b60405180910390f35b610cfe613a15565b604051610d0b919061525b565b60405180910390f35b610d1c613a1d565b604051610d29919061525b565b60405180910390f35b610d3a613a25565b604051610d47919061525b565b60405180910390f35b610d58613a2d565b604051610d65919061525b565b60405180910390f35b610d76613a35565b604051610d83919061525b565b60405180910390f35b610da66004803603810190610da19190615139565b613a3d565b604051610db391906151a3565b60405180910390f35b610dc4613d1d565b604051610dd1919061525b565b60405180910390f35b610de2613d25565b604051610def919061522c565b60405180910390f35b610e00613db1565b604051610e0d919061525b565b60405180910390f35b610e1e613db9565b604051610e2b919061525b565b60405180910390f35b610e3c613dc1565b604051610e49919061525b565b60405180910390f35b610e6c6004803603810190610e679190615274565b613dc9565b604051610e7991906151a3565b60405180910390f35b610e8a613f5f565b604051610e97919061525b565b60405180910390f35b610eba6004803603810190610eb59190615139565b613f67565b604051610ec791906151a3565b60405180910390f35b610ed8614247565b604051610ee5919061525b565b60405180910390f35b610f086004803603810190610f039190615139565b61424f565b604051610f1591906151a3565b60405180910390f35b610f2661452f565b604051610f33919061525b565b60405180910390f35b610f44614537565b604051610f51919061525b565b60405180910390f35b610f746004803603810190610f6f9190615139565b61453f565b604051610f8191906151a3565b60405180910390f35b610f9261481f565b604051610f9f919061525b565b60405180910390f35b610fc26004803603810190610fbd9190615139565b614843565b604051610fcf91906151a3565b60405180910390f35b610fe0614b23565b604051610fed919061525b565b60405180910390f35b610ffe614b2b565b60405161100b919061525b565b60405180910390f35b61101c614b33565b604051611029919061525b565b60405180910390f35b61103a614b3b565b604051611047919061525b565b60405180910390f35b611058614b43565b604051611065919061525b565b60405180910390f35b61108860048036038101906110839190615311565b614b4b565b604051611095919061525b565b60405180910390f35b6110a6614b6b565b6040516110b3919061525b565b60405180910390f35b6110c4614b73565b6040516110d1919061525b565b60405180910390f35b6110f460048036038101906110ef9190615139565b614b7b565b60405161110191906151a3565b60405180910390f35b611112614da0565b60405161111f919061525b565b60405180910390f35b611130614da8565b60405161113d919061525b565b60405180910390f35b61114e614db0565b60405161115b919061525b565b60405180910390f35b61117e60048036038101906111799190615139565b614db8565b60405161118b91906151a3565b60405180910390f35b61119c615098565b6040516111a9919061525b565b60405180910390f35b6111ba6150a0565b6040516111c7919061525b565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124890615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561130c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130390615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611358919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546113ab919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611439919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161149d919061525b565b60405180910390a3600190509392505050565b5f80546114bc906154df565b80601f01602080910402602001604051908101604052809291908181526020018280546114e8906154df565b80156115335780601f1061150a57610100808354040283529160200191611533565b820191905f5260205f20905b81548152906001019060200180831161151657829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161161e919061525b565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156116ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156117aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546117f6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611849919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546118d7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161193b919061525b565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156119cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611a8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ad6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611b29919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611bb7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c1b919061525b565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611d9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611de6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611e39919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ec7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611f2b919061525b565b60405180910390a3600190509392505050565b5f6001905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611fc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fbe90615559565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612082576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612079906155c1565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546120ce919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612121919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546121af919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612213919061525b565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546123d0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612423919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546124b1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612515919061525b565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156125a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125a090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546126b0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612703919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612791919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516127f5919061525b565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156128b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161296b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546129c0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612a13919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612aa1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b05919061525b565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612bb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c6b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612cc0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612d13919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612da1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612e05919061525b565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ea1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9890615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612f5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5390615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612fa8919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ffb919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613089919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130ed919061525b565b60405180910390a3600190509392505050565b5f6009905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156131a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a090615559565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161325b906155c1565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546132b0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613303919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613391919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516133f5919061525b565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613499576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161354b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135a0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135f3919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613681919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516136e5919061525b565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156137b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137ad90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161386890615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546138bd919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613910919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461399e919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613a02919061525b565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613abe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ab590615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613b79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b7090615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613bc5919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613c18919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ca6919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613d0a919061525b565b60405180910390a3600190509392505050565b5f600b905090565b60018054613d32906154df565b80601f0160208091040260200160405190810160405280929190818152602001828054613d5e906154df565b8015613da95780601f10613d8057610100808354040283529160200191613da9565b820191905f5260205f20905b815481529060010190602001808311613d8c57829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613e4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e4190615399565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e96919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ee9919061547f565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613f4d919061525b565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613fe8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fdf90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156140a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161409a90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546140ef919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614142919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546141d0919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614234919061525b565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156142d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016142c790615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561438b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161438290615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546143d7919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461442a919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546144b8919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161451c919061525b565b60405180910390a3600190509392505050565b5f6018905090565b5f600f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156145c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016145b790615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561467b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161467290615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146c7919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461471a919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546147a8919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161480c919061525b565b60405180910390a3600190509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156148c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148bb90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561497f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161497690615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546149cb919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614a1e919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614aac919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614b10919061525b565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614bfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614bf390615559565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c48919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c9b919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d29919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614d8d919061525b565b60405180910390a3600190509392505050565b5f6007905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614e39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614e3090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614ef4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614eeb90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f40919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f93919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254615021919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051615085919061525b565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6150d5826150ac565b9050919050565b6150e5816150cb565b81146150ef575f5ffd5b50565b5f81359050615100816150dc565b92915050565b5f819050919050565b61511881615106565b8114615122575f5ffd5b50565b5f813590506151338161510f565b92915050565b5f5f5f606084860312156151505761514f6150a8565b5b5f61515d868287016150f2565b935050602061516e868287016150f2565b925050604061517f86828701615125565b9150509250925092565b5f8115159050919050565b61519d81615189565b82525050565b5f6020820190506151b65f830184615194565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6151fe826151bc565b61520881856151c6565b93506152188185602086016151d6565b615221816151e4565b840191505092915050565b5f6020820190508181035f83015261524481846151f4565b905092915050565b61525581615106565b82525050565b5f60208201905061526e5f83018461524c565b92915050565b5f5f6040838503121561528a576152896150a8565b5b5f615297858286016150f2565b92505060206152a885828601615125565b9150509250929050565b5f60ff82169050919050565b6152c7816152b2565b82525050565b5f6020820190506152e05f8301846152be565b92915050565b5f602082840312156152fb576152fa6150a8565b5b5f615308848285016150f2565b91505092915050565b5f5f60408385031215615327576153266150a8565b5b5f615334858286016150f2565b9250506020615345858286016150f2565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6153836014836151c6565b915061538e8261534f565b602082019050919050565b5f6020820190508181035f8301526153b081615377565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f6153eb6016836151c6565b91506153f6826153b7565b602082019050919050565b5f6020820190508181035f830152615418816153df565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61545682615106565b915061546183615106565b92508282039050818111156154795761547861541f565b5b92915050565b5f61548982615106565b915061549483615106565b92508282019050808211156154ac576154ab61541f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806154f657607f821691505b602082108103615509576155086154b2565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6155436001836151c6565b915061554e8261550f565b602082019050919050565b5f6020820190508181035f83015261557081615537565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6155ab6001836151c6565b91506155b682615577565b602082019050919050565b5f6020820190508181035f8301526155d88161559f565b905091905056fea26469706673582212206fbf384dcd110eb4456b07e83a2c8a392433c7852a66dec9f8ebf3989cad1f6764736f6c634300081e0033 \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go index f744e474..13a8ab62 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go @@ -31,8 +31,8 @@ var ( // ContractMetaData contains all meta data concerning the Contract contract. var ContractMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy10\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy11\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy12\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy13\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy14\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy15\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy16\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy17\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy18\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy19\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy2\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy20\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy21\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy22\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy23\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy24\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy25\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy26\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy27\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy28\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy29\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy3\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy30\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy31\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy32\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy33\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy34\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy35\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy36\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy37\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy38\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy39\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy4\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy40\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy41\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy42\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy43\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy44\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy45\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy46\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy47\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy48\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy49\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy5\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy50\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy51\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy52\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy53\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy54\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy55\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy56\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy57\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy58\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy59\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy6\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy60\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy61\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy62\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy63\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy64\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy65\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy66\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy67\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy68\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy69\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy7\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy70\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy71\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy72\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy73\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy74\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy75\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy8\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy9\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"salt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom1\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom10\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom11\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom12\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom13\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom14\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom15\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom16\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom17\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom18\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom19\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom3\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom4\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom5\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom6\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom7\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom8\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom9\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561000f575f5ffd5b50604051615fd4380380615fd4833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b60805161587f6107555f395f614a7b015261587f5ff3fe608060405234801561000f575f5ffd5b5060043610610606575f3560e01c8063657b6ef711610319578063b1802b9a116101a6578063d9bb3174116100f2578063f26c779b116100ab578063f8716f1411610085578063f8716f1414611360578063faf35ced1461137e578063fe7d5996146113ae578063ffbf0469146113cc57610606565b8063f26c779b14611306578063f4978b0414611324578063f5f573811461134257610606565b8063d9bb31741461122e578063dc1d8a9b1461124c578063dd62ed3e1461126a578063e2d275301461129a578063e8c927b3146112b8578063eb4329c8146112d657610606565b8063bbe231321161015f578063c958d4bf11610139578063c958d4bf146111b6578063cfd66863146111d4578063d101dcd0146111f2578063d74194691461121057610606565b8063bbe231321461114a578063bfa0b13314611168578063c2be97e31461118657610606565b8063b1802b9a14611072578063b2bb360e146110a2578063b4c48668146110c0578063b66dd750146110de578063b9a6d645146110fc578063bb9bfe061461111a57610606565b80637e544937116102655780639c5dfe731161021e578063a9059cbb116101f8578063a9059cbb14610fd6578063aaa7af7014611006578063acc5aee914611024578063ad8f42211461105457610606565b80639c5dfe7314610f7c5780639df61a2514610f9a578063a891d4d414610fb857610606565b80637e54493714610eb65780637f34d94b14610ed45780638619d60714610ef25780638789ca6714610f105780638f4a840614610f4057806395d89b4114610f5e57610606565b806374f83d02116102d25780637a319c18116102ac5780637a319c1814610e2c5780637c66673e14610e4a5780637c72ed0d14610e7a5780637dffdc3214610e9857610606565b806374f83d0214610dd257806377c0209e14610df0578063792c7f3e14610e0e57610606565b8063657b6ef714610ce8578063672151fe14610d185780636abceacd14610d365780636c12ed2814610d5457806370a0823114610d8457806374e73fd314610db457610606565b8063313ce567116104975780634b3c7f5f116103e357806358b6a9bd1161039c57806361b970eb1161037657806361b970eb14610c70578063639ec53a14610c8e5780636547317414610cac5780636578534c14610cca57610606565b806358b6a9bd14610c16578063595471b814610c345780635af92c0514610c5257610606565b80634b3c7f5f14610b3e5780634e1dbb8214610b5c5780634f5e555714610b7a5780634f7bd75a14610b9857806354c2792014610bc8578063552a1b5614610be657610606565b80633ea117ce1161045057806342937dbd1161042a57806342937dbd14610ab457806343a6b92d14610ad257806344050a2814610af05780634a2e93c614610b2057610606565b80633ea117ce14610a5a5780634128a85d14610a78578063418b181614610a9657610606565b8063313ce5671461098257806334517f0b146109a0578063378c5382146109be57806339e0bd12146109dc5780633a13199014610a0c5780633b6be45914610a3c57610606565b80631bbffe6f1161055657806321ecd7a31161050f5780632545d8b7116104e95780632545d8b7146108f85780632787325b14610916578063291c3bd7146109345780633125f37a1461096457610606565b806321ecd7a31461088c578063239af2a5146108aa57806323b872dd146108c857610606565b80631bbffe6f146107c65780631d527cde146107f65780631eaa7c52146108145780631f29783f146108325780631f449589146108505780631fd298ec1461086e57610606565b806312901b42116105c357806318160ddd1161059d57806318160ddd1461073c57806319cf6a911461075a5780631a97f18e146107785780631b17c65c1461079657610606565b806312901b42146106e257806313ebb5ec1461070057806316a3045b1461071e57610606565b80630460faf61461060a57806306fdde031461063a5780630717b16114610658578063095ea7b3146106765780630cb7a9e7146106a65780631215a3ab146106c4575b5f5ffd5b610624600480360381019061061f91906153a3565b6113ea565b604051610631919061540d565b60405180910390f35b6106426116ca565b60405161064f9190615496565b60405180910390f35b610660611755565b60405161066d91906154c5565b60405180910390f35b610690600480360381019061068b91906154de565b61175d565b60405161069d919061540d565b60405180910390f35b6106ae61184a565b6040516106bb91906154c5565b60405180910390f35b6106cc611852565b6040516106d991906154c5565b60405180910390f35b6106ea61185a565b6040516106f791906154c5565b60405180910390f35b610708611862565b60405161071591906154c5565b60405180910390f35b61072661186a565b60405161073391906154c5565b60405180910390f35b610744611872565b60405161075191906154c5565b60405180910390f35b610762611878565b60405161076f91906154c5565b60405180910390f35b610780611880565b60405161078d91906154c5565b60405180910390f35b6107b060048036038101906107ab91906153a3565b611888565b6040516107bd919061540d565b60405180910390f35b6107e060048036038101906107db91906153a3565b611b68565b6040516107ed919061540d565b60405180910390f35b6107fe611e48565b60405161080b91906154c5565b60405180910390f35b61081c611e50565b60405161082991906154c5565b60405180910390f35b61083a611e58565b60405161084791906154c5565b60405180910390f35b610858611e60565b60405161086591906154c5565b60405180910390f35b610876611e68565b60405161088391906154c5565b60405180910390f35b610894611e70565b6040516108a191906154c5565b60405180910390f35b6108b2611e78565b6040516108bf91906154c5565b60405180910390f35b6108e260048036038101906108dd91906153a3565b611e80565b6040516108ef919061540d565b60405180910390f35b610900612160565b60405161090d91906154c5565b60405180910390f35b61091e612168565b60405161092b91906154c5565b60405180910390f35b61094e600480360381019061094991906153a3565b612170565b60405161095b919061540d565b60405180910390f35b61096c612450565b60405161097991906154c5565b60405180910390f35b61098a612458565b6040516109979190615537565b60405180910390f35b6109a861246a565b6040516109b591906154c5565b60405180910390f35b6109c6612472565b6040516109d391906154c5565b60405180910390f35b6109f660048036038101906109f191906153a3565b61247a565b604051610a03919061540d565b60405180910390f35b610a266004803603810190610a2191906153a3565b61275a565b604051610a33919061540d565b60405180910390f35b610a44612a3a565b604051610a5191906154c5565b60405180910390f35b610a62612a42565b604051610a6f91906154c5565b60405180910390f35b610a80612a4a565b604051610a8d91906154c5565b60405180910390f35b610a9e612a52565b604051610aab91906154c5565b60405180910390f35b610abc612a5a565b604051610ac991906154c5565b60405180910390f35b610ada612a62565b604051610ae791906154c5565b60405180910390f35b610b0a6004803603810190610b0591906153a3565b612a6a565b604051610b17919061540d565b60405180910390f35b610b28612d4a565b604051610b3591906154c5565b60405180910390f35b610b46612d52565b604051610b5391906154c5565b60405180910390f35b610b64612d5a565b604051610b7191906154c5565b60405180910390f35b610b82612d62565b604051610b8f91906154c5565b60405180910390f35b610bb26004803603810190610bad91906153a3565b612d6a565b604051610bbf919061540d565b60405180910390f35b610bd061304a565b604051610bdd91906154c5565b60405180910390f35b610c006004803603810190610bfb91906153a3565b613052565b604051610c0d919061540d565b60405180910390f35b610c1e613332565b604051610c2b91906154c5565b60405180910390f35b610c3c61333a565b604051610c4991906154c5565b60405180910390f35b610c5a613342565b604051610c6791906154c5565b60405180910390f35b610c7861334a565b604051610c8591906154c5565b60405180910390f35b610c96613352565b604051610ca391906154c5565b60405180910390f35b610cb461335a565b604051610cc191906154c5565b60405180910390f35b610cd2613362565b604051610cdf91906154c5565b60405180910390f35b610d026004803603810190610cfd91906153a3565b61336a565b604051610d0f919061540d565b60405180910390f35b610d2061364a565b604051610d2d91906154c5565b60405180910390f35b610d3e613652565b604051610d4b91906154c5565b60405180910390f35b610d6e6004803603810190610d6991906153a3565b61365a565b604051610d7b919061540d565b60405180910390f35b610d9e6004803603810190610d999190615550565b61393a565b604051610dab91906154c5565b60405180910390f35b610dbc61394f565b604051610dc991906154c5565b60405180910390f35b610dda613957565b604051610de791906154c5565b60405180910390f35b610df861395f565b604051610e0591906154c5565b60405180910390f35b610e16613967565b604051610e2391906154c5565b60405180910390f35b610e3461396f565b604051610e4191906154c5565b60405180910390f35b610e646004803603810190610e5f91906153a3565b613977565b604051610e71919061540d565b60405180910390f35b610e82613c57565b604051610e8f91906154c5565b60405180910390f35b610ea0613c5f565b604051610ead91906154c5565b60405180910390f35b610ebe613c67565b604051610ecb91906154c5565b60405180910390f35b610edc613c6f565b604051610ee991906154c5565b60405180910390f35b610efa613c77565b604051610f0791906154c5565b60405180910390f35b610f2a6004803603810190610f2591906153a3565b613c7f565b604051610f37919061540d565b60405180910390f35b610f48613f5f565b604051610f5591906154c5565b60405180910390f35b610f66613f67565b604051610f739190615496565b60405180910390f35b610f84613ff3565b604051610f9191906154c5565b60405180910390f35b610fa2613ffb565b604051610faf91906154c5565b60405180910390f35b610fc0614003565b604051610fcd91906154c5565b60405180910390f35b610ff06004803603810190610feb91906154de565b61400b565b604051610ffd919061540d565b60405180910390f35b61100e6141a1565b60405161101b91906154c5565b60405180910390f35b61103e600480360381019061103991906153a3565b6141a9565b60405161104b919061540d565b60405180910390f35b61105c614489565b60405161106991906154c5565b60405180910390f35b61108c600480360381019061108791906153a3565b614491565b604051611099919061540d565b60405180910390f35b6110aa614771565b6040516110b791906154c5565b60405180910390f35b6110c8614779565b6040516110d591906154c5565b60405180910390f35b6110e6614781565b6040516110f391906154c5565b60405180910390f35b611104614789565b60405161111191906154c5565b60405180910390f35b611134600480360381019061112f91906153a3565b614791565b604051611141919061540d565b60405180910390f35b611152614a71565b60405161115f91906154c5565b60405180910390f35b611170614a79565b60405161117d91906154c5565b60405180910390f35b6111a0600480360381019061119b91906153a3565b614a9d565b6040516111ad919061540d565b60405180910390f35b6111be614d7d565b6040516111cb91906154c5565b60405180910390f35b6111dc614d85565b6040516111e991906154c5565b60405180910390f35b6111fa614d8d565b60405161120791906154c5565b60405180910390f35b611218614d95565b60405161122591906154c5565b60405180910390f35b611236614d9d565b60405161124391906154c5565b60405180910390f35b611254614da5565b60405161126191906154c5565b60405180910390f35b611284600480360381019061127f919061557b565b614dad565b60405161129191906154c5565b60405180910390f35b6112a2614dcd565b6040516112af91906154c5565b60405180910390f35b6112c0614dd5565b6040516112cd91906154c5565b60405180910390f35b6112f060048036038101906112eb91906153a3565b614ddd565b6040516112fd919061540d565b60405180910390f35b61130e615002565b60405161131b91906154c5565b60405180910390f35b61132c61500a565b60405161133991906154c5565b60405180910390f35b61134a615012565b60405161135791906154c5565b60405180910390f35b61136861501a565b60405161137591906154c5565b60405180910390f35b611398600480360381019061139391906153a3565b615022565b6040516113a5919061540d565b60405180910390f35b6113b6615302565b6040516113c391906154c5565b60405180910390f35b6113d461530a565b6040516113e191906154c5565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561146b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461157291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546115c591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461165391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516116b791906154c5565b60405180910390a3600190509392505050565b5f80546116d690615749565b80601f016020809104026020016040519081016040528092919081815260200182805461170290615749565b801561174d5780601f106117245761010080835404028352916020019161174d565b820191905f5260205f20905b81548152906001019060200180831161173057829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161183891906154c5565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190090615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156119c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bb9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611a1091906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611a6391906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611af191906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611b5591906154c5565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611be9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be090615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9b9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611cf091906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611d4391906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611dd191906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611e3591906154c5565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6048905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611fbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb39061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461200891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461205b91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546120e991906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161214d91906154c5565b60405180910390a3600190509392505050565b5f6001905090565b5f6045905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156121f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e8906157c3565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156122ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a39061582b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546122f891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461234b91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546123d991906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161243d91906154c5565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f604b905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156124fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156125b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ad9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461260291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461265591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546126e391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161274791906154c5565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156127db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546128e291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461293591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546129c391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612a2791906154c5565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612aeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ba6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612bf291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612c4591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612cd391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612d3791906154c5565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612de290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ea6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ef291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612f4591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612fd391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161303791906154c5565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156130d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ca90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561318e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131859061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546131da91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461322d91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546132bb91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161331f91906154c5565b60405180910390a3600190509392505050565b5f6009905090565b5f6049905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f6043905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156133eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133e2906157c3565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156134a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349d9061582b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546134f291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461354591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135d391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161363791906154c5565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156136db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136d290615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161378d9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546137e291906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461383591906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546138c391906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161392791906154c5565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156139f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139ef90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613ab3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613aaa9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613aff91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613b5291906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613be091906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613c4491906154c5565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613d00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613cf790615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613dbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613db29061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e0791906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e5a91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ee891906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613f4c91906154c5565b60405180910390a3600190509392505050565b5f600b905090565b60018054613f7490615749565b80601f0160208091040260200160405190810160405280929190818152602001828054613fa090615749565b8015613feb5780601f10613fc257610100808354040283529160200191613feb565b820191905f5260205f20905b815481529060010190602001808311613fce57829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561408c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161408390615603565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546140d891906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461412b91906156e9565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161418f91906154c5565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561422a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161422190615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156142e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016142dc9061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461433191906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461438491906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461441291906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161447691906154c5565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161450990615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156145cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016145c49061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461461991906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461466c91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146fa91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161475e91906154c5565b60405180910390a3600190509392505050565b5f6018905090565b5f604a905090565b5f600f905090565b5f6044905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161480990615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156148cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148c49061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461491991906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461496c91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546149fa91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614a5e91906154c5565b60405180910390a3600190509392505050565b5f6046905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614b1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614b1590615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614bd09061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c2591906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c7891906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d0691906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614d6a91906154c5565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6042905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614e55906157c3565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614eaa91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614efd91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f8b91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614fef91906154c5565b60405180910390a3600190509392505050565b5f6007905090565b5f6047905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156150a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161509a90615603565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561515e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016151559061566b565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546151aa91906156b6565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546151fd91906156e9565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461528b91906156b6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516152ef91906154c5565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61533f82615316565b9050919050565b61534f81615335565b8114615359575f5ffd5b50565b5f8135905061536a81615346565b92915050565b5f819050919050565b61538281615370565b811461538c575f5ffd5b50565b5f8135905061539d81615379565b92915050565b5f5f5f606084860312156153ba576153b9615312565b5b5f6153c78682870161535c565b93505060206153d88682870161535c565b92505060406153e98682870161538f565b9150509250925092565b5f8115159050919050565b615407816153f3565b82525050565b5f6020820190506154205f8301846153fe565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61546882615426565b6154728185615430565b9350615482818560208601615440565b61548b8161544e565b840191505092915050565b5f6020820190508181035f8301526154ae818461545e565b905092915050565b6154bf81615370565b82525050565b5f6020820190506154d85f8301846154b6565b92915050565b5f5f604083850312156154f4576154f3615312565b5b5f6155018582860161535c565b92505060206155128582860161538f565b9150509250929050565b5f60ff82169050919050565b6155318161551c565b82525050565b5f60208201905061554a5f830184615528565b92915050565b5f6020828403121561556557615564615312565b5b5f6155728482850161535c565b91505092915050565b5f5f6040838503121561559157615590615312565b5b5f61559e8582860161535c565b92505060206155af8582860161535c565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6155ed601483615430565b91506155f8826155b9565b602082019050919050565b5f6020820190508181035f83015261561a816155e1565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f615655601683615430565b915061566082615621565b602082019050919050565b5f6020820190508181035f83015261568281615649565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6156c082615370565b91506156cb83615370565b92508282039050818111156156e3576156e2615689565b5b92915050565b5f6156f382615370565b91506156fe83615370565b925082820190508082111561571657615715615689565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061576057607f821691505b6020821081036157735761577261571c565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6157ad600183615430565b91506157b882615779565b602082019050919050565b5f6020820190508181035f8301526157da816157a1565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f615815600183615430565b9150615820826157e1565b602082019050919050565b5f6020820190508181035f83015261584281615809565b905091905056fea2646970667358221220ce03f2ea0f8ec341a07b9c0512b41f44d879b740c55b3572c5707216663e8a3f64736f6c634300081e0033", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy10\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy11\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy12\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy13\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy14\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy15\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy16\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy17\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy18\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy19\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy2\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy20\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy21\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy22\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy23\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy24\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy25\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy26\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy27\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy28\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy29\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy3\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy30\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy31\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy32\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy33\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy34\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy35\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy36\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy37\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy38\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy39\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy4\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy40\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy41\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy42\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy43\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy44\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy45\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy46\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy47\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy48\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy49\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy5\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy50\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy51\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy52\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy53\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy54\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy55\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy56\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy57\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy58\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy59\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy6\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy60\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy61\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy62\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy63\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy64\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy65\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy7\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy8\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy9\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"salt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom1\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom10\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom11\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom12\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom13\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom14\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom15\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom16\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom17\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom18\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom19\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom3\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom4\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom5\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom6\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom7\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom8\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom9\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561000f575f5ffd5b50604051615d6a380380615d6a833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b6080516156156107555f395f61482101526156155ff3fe608060405234801561000f575f5ffd5b5060043610610518575f3560e01c8063657b6ef7116102a2578063aaa7af7011610170578063d7419469116100d7578063f26c779b11610090578063f26c779b1461110a578063f5f5738114611128578063f8716f1414611146578063faf35ced14611164578063fe7d599614611194578063ffbf0469146111b257610518565b8063d741946914611032578063dc1d8a9b14611050578063dd62ed3e1461106e578063e2d275301461109e578063e8c927b3146110bc578063eb4329c8146110da57610518565b8063bb9bfe0611610129578063bb9bfe0614610f5a578063bfa0b13314610f8a578063c2be97e314610fa8578063c958d4bf14610fd8578063cfd6686314610ff6578063d101dcd01461101457610518565b8063aaa7af7014610e82578063acc5aee914610ea0578063ad8f422114610ed0578063b1802b9a14610eee578063b2bb360e14610f1e578063b66dd75014610f3c57610518565b80637c72ed0d116102145780638f4a8406116101cd5780638f4a840614610dbc57806395d89b4114610dda5780639c5dfe7314610df85780639df61a2514610e16578063a891d4d414610e34578063a9059cbb14610e5257610518565b80637c72ed0d14610cf65780637dffdc3214610d145780637e54493714610d325780637f34d94b14610d505780638619d60714610d6e5780638789ca6714610d8c57610518565b806374e73fd31161026657806374e73fd314610c3057806374f83d0214610c4e57806377c0209e14610c6c578063792c7f3e14610c8a5780637a319c1814610ca85780637c66673e14610cc657610518565b8063657b6ef714610b64578063672151fe14610b945780636abceacd14610bb25780636c12ed2814610bd057806370a0823114610c0057610518565b80633125f37a116103ea5780634a2e93c611610351578063552a1b561161030a578063552a1b5614610a9e57806358b6a9bd14610ace5780635af92c0514610aec57806361b970eb14610b0a578063639ec53a14610b285780636547317414610b4657610518565b80634a2e93c6146109d85780634b3c7f5f146109f65780634e1dbb8214610a145780634f5e555714610a325780634f7bd75a14610a5057806354c2792014610a8057610518565b80633ea117ce116103a35780633ea117ce146109125780634128a85d14610930578063418b18161461094e57806342937dbd1461096c57806343a6b92d1461098a57806344050a28146109a857610518565b80633125f37a1461083a578063313ce5671461085857806334517f0b1461087657806339e0bd12146108945780633a131990146108c45780633b6be459146108f457610518565b80631a97f18e1161048e5780631fd298ec116104475780631fd298ec1461076257806321ecd7a314610780578063239af2a51461079e57806323b872dd146107bc5780632545d8b7146107ec578063291c3bd71461080a57610518565b80631a97f18e1461068a5780631b17c65c146106a85780631bbffe6f146106d85780631d527cde146107085780631eaa7c52146107265780631f4495891461074457610518565b80631215a3ab116104e05780631215a3ab146105d657806312901b42146105f457806313ebb5ec1461061257806316a3045b1461063057806318160ddd1461064e57806319cf6a911461066c57610518565b80630460faf61461051c57806306fdde031461054c5780630717b1611461056a578063095ea7b3146105885780630cb7a9e7146105b8575b5f5ffd5b61053660048036038101906105319190615139565b6111d0565b60405161054391906151a3565b60405180910390f35b6105546114b0565b604051610561919061522c565b60405180910390f35b61057261153b565b60405161057f919061525b565b60405180910390f35b6105a2600480360381019061059d9190615274565b611543565b6040516105af91906151a3565b60405180910390f35b6105c0611630565b6040516105cd919061525b565b60405180910390f35b6105de611638565b6040516105eb919061525b565b60405180910390f35b6105fc611640565b604051610609919061525b565b60405180910390f35b61061a611648565b604051610627919061525b565b60405180910390f35b610638611650565b604051610645919061525b565b60405180910390f35b610656611658565b604051610663919061525b565b60405180910390f35b61067461165e565b604051610681919061525b565b60405180910390f35b610692611666565b60405161069f919061525b565b60405180910390f35b6106c260048036038101906106bd9190615139565b61166e565b6040516106cf91906151a3565b60405180910390f35b6106f260048036038101906106ed9190615139565b61194e565b6040516106ff91906151a3565b60405180910390f35b610710611c2e565b60405161071d919061525b565b60405180910390f35b61072e611c36565b60405161073b919061525b565b60405180910390f35b61074c611c3e565b604051610759919061525b565b60405180910390f35b61076a611c46565b604051610777919061525b565b60405180910390f35b610788611c4e565b604051610795919061525b565b60405180910390f35b6107a6611c56565b6040516107b3919061525b565b60405180910390f35b6107d660048036038101906107d19190615139565b611c5e565b6040516107e391906151a3565b60405180910390f35b6107f4611f3e565b604051610801919061525b565b60405180910390f35b610824600480360381019061081f9190615139565b611f46565b60405161083191906151a3565b60405180910390f35b610842612226565b60405161084f919061525b565b60405180910390f35b61086061222e565b60405161086d91906152cd565b60405180910390f35b61087e612240565b60405161088b919061525b565b60405180910390f35b6108ae60048036038101906108a99190615139565b612248565b6040516108bb91906151a3565b60405180910390f35b6108de60048036038101906108d99190615139565b612528565b6040516108eb91906151a3565b60405180910390f35b6108fc612808565b604051610909919061525b565b60405180910390f35b61091a612810565b604051610927919061525b565b60405180910390f35b610938612818565b604051610945919061525b565b60405180910390f35b610956612820565b604051610963919061525b565b60405180910390f35b610974612828565b604051610981919061525b565b60405180910390f35b610992612830565b60405161099f919061525b565b60405180910390f35b6109c260048036038101906109bd9190615139565b612838565b6040516109cf91906151a3565b60405180910390f35b6109e0612b18565b6040516109ed919061525b565b60405180910390f35b6109fe612b20565b604051610a0b919061525b565b60405180910390f35b610a1c612b28565b604051610a29919061525b565b60405180910390f35b610a3a612b30565b604051610a47919061525b565b60405180910390f35b610a6a6004803603810190610a659190615139565b612b38565b604051610a7791906151a3565b60405180910390f35b610a88612e18565b604051610a95919061525b565b60405180910390f35b610ab86004803603810190610ab39190615139565b612e20565b604051610ac591906151a3565b60405180910390f35b610ad6613100565b604051610ae3919061525b565b60405180910390f35b610af4613108565b604051610b01919061525b565b60405180910390f35b610b12613110565b604051610b1f919061525b565b60405180910390f35b610b30613118565b604051610b3d919061525b565b60405180910390f35b610b4e613120565b604051610b5b919061525b565b60405180910390f35b610b7e6004803603810190610b799190615139565b613128565b604051610b8b91906151a3565b60405180910390f35b610b9c613408565b604051610ba9919061525b565b60405180910390f35b610bba613410565b604051610bc7919061525b565b60405180910390f35b610bea6004803603810190610be59190615139565b613418565b604051610bf791906151a3565b60405180910390f35b610c1a6004803603810190610c1591906152e6565b6136f8565b604051610c27919061525b565b60405180910390f35b610c3861370d565b604051610c45919061525b565b60405180910390f35b610c56613715565b604051610c63919061525b565b60405180910390f35b610c7461371d565b604051610c81919061525b565b60405180910390f35b610c92613725565b604051610c9f919061525b565b60405180910390f35b610cb061372d565b604051610cbd919061525b565b60405180910390f35b610ce06004803603810190610cdb9190615139565b613735565b604051610ced91906151a3565b60405180910390f35b610cfe613a15565b604051610d0b919061525b565b60405180910390f35b610d1c613a1d565b604051610d29919061525b565b60405180910390f35b610d3a613a25565b604051610d47919061525b565b60405180910390f35b610d58613a2d565b604051610d65919061525b565b60405180910390f35b610d76613a35565b604051610d83919061525b565b60405180910390f35b610da66004803603810190610da19190615139565b613a3d565b604051610db391906151a3565b60405180910390f35b610dc4613d1d565b604051610dd1919061525b565b60405180910390f35b610de2613d25565b604051610def919061522c565b60405180910390f35b610e00613db1565b604051610e0d919061525b565b60405180910390f35b610e1e613db9565b604051610e2b919061525b565b60405180910390f35b610e3c613dc1565b604051610e49919061525b565b60405180910390f35b610e6c6004803603810190610e679190615274565b613dc9565b604051610e7991906151a3565b60405180910390f35b610e8a613f5f565b604051610e97919061525b565b60405180910390f35b610eba6004803603810190610eb59190615139565b613f67565b604051610ec791906151a3565b60405180910390f35b610ed8614247565b604051610ee5919061525b565b60405180910390f35b610f086004803603810190610f039190615139565b61424f565b604051610f1591906151a3565b60405180910390f35b610f2661452f565b604051610f33919061525b565b60405180910390f35b610f44614537565b604051610f51919061525b565b60405180910390f35b610f746004803603810190610f6f9190615139565b61453f565b604051610f8191906151a3565b60405180910390f35b610f9261481f565b604051610f9f919061525b565b60405180910390f35b610fc26004803603810190610fbd9190615139565b614843565b604051610fcf91906151a3565b60405180910390f35b610fe0614b23565b604051610fed919061525b565b60405180910390f35b610ffe614b2b565b60405161100b919061525b565b60405180910390f35b61101c614b33565b604051611029919061525b565b60405180910390f35b61103a614b3b565b604051611047919061525b565b60405180910390f35b611058614b43565b604051611065919061525b565b60405180910390f35b61108860048036038101906110839190615311565b614b4b565b604051611095919061525b565b60405180910390f35b6110a6614b6b565b6040516110b3919061525b565b60405180910390f35b6110c4614b73565b6040516110d1919061525b565b60405180910390f35b6110f460048036038101906110ef9190615139565b614b7b565b60405161110191906151a3565b60405180910390f35b611112614da0565b60405161111f919061525b565b60405180910390f35b611130614da8565b60405161113d919061525b565b60405180910390f35b61114e614db0565b60405161115b919061525b565b60405180910390f35b61117e60048036038101906111799190615139565b614db8565b60405161118b91906151a3565b60405180910390f35b61119c615098565b6040516111a9919061525b565b60405180910390f35b6111ba6150a0565b6040516111c7919061525b565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124890615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561130c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130390615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611358919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546113ab919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611439919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161149d919061525b565b60405180910390a3600190509392505050565b5f80546114bc906154df565b80601f01602080910402602001604051908101604052809291908181526020018280546114e8906154df565b80156115335780601f1061150a57610100808354040283529160200191611533565b820191905f5260205f20905b81548152906001019060200180831161151657829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161161e919061525b565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156116ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156117aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546117f6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611849919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546118d7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161193b919061525b565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156119cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611a8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ad6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611b29919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611bb7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c1b919061525b565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611d9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611de6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611e39919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ec7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611f2b919061525b565b60405180910390a3600190509392505050565b5f6001905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611fc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fbe90615559565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612082576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612079906155c1565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546120ce919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612121919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546121af919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612213919061525b565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546123d0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612423919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546124b1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612515919061525b565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156125a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125a090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546126b0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612703919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612791919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516127f5919061525b565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156128b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161296b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546129c0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612a13919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612aa1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b05919061525b565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612bb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c6b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612cc0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612d13919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612da1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612e05919061525b565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ea1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9890615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612f5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5390615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612fa8919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ffb919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613089919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130ed919061525b565b60405180910390a3600190509392505050565b5f6009905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156131a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a090615559565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161325b906155c1565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546132b0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613303919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613391919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516133f5919061525b565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613499576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161354b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135a0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135f3919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613681919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516136e5919061525b565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156137b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137ad90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161386890615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546138bd919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613910919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461399e919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613a02919061525b565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613abe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ab590615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613b79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b7090615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613bc5919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613c18919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ca6919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613d0a919061525b565b60405180910390a3600190509392505050565b5f600b905090565b60018054613d32906154df565b80601f0160208091040260200160405190810160405280929190818152602001828054613d5e906154df565b8015613da95780601f10613d8057610100808354040283529160200191613da9565b820191905f5260205f20905b815481529060010190602001808311613d8c57829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613e4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e4190615399565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e96919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ee9919061547f565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613f4d919061525b565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613fe8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fdf90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156140a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161409a90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546140ef919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614142919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546141d0919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614234919061525b565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156142d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016142c790615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561438b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161438290615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546143d7919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461442a919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546144b8919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161451c919061525b565b60405180910390a3600190509392505050565b5f6018905090565b5f600f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156145c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016145b790615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561467b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161467290615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146c7919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461471a919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546147a8919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161480c919061525b565b60405180910390a3600190509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156148c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148bb90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561497f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161497690615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546149cb919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614a1e919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614aac919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614b10919061525b565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614bfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614bf390615559565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c48919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c9b919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d29919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614d8d919061525b565b60405180910390a3600190509392505050565b5f6007905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614e39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614e3090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614ef4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614eeb90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f40919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f93919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254615021919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051615085919061525b565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6150d5826150ac565b9050919050565b6150e5816150cb565b81146150ef575f5ffd5b50565b5f81359050615100816150dc565b92915050565b5f819050919050565b61511881615106565b8114615122575f5ffd5b50565b5f813590506151338161510f565b92915050565b5f5f5f606084860312156151505761514f6150a8565b5b5f61515d868287016150f2565b935050602061516e868287016150f2565b925050604061517f86828701615125565b9150509250925092565b5f8115159050919050565b61519d81615189565b82525050565b5f6020820190506151b65f830184615194565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6151fe826151bc565b61520881856151c6565b93506152188185602086016151d6565b615221816151e4565b840191505092915050565b5f6020820190508181035f83015261524481846151f4565b905092915050565b61525581615106565b82525050565b5f60208201905061526e5f83018461524c565b92915050565b5f5f6040838503121561528a576152896150a8565b5b5f615297858286016150f2565b92505060206152a885828601615125565b9150509250929050565b5f60ff82169050919050565b6152c7816152b2565b82525050565b5f6020820190506152e05f8301846152be565b92915050565b5f602082840312156152fb576152fa6150a8565b5b5f615308848285016150f2565b91505092915050565b5f5f60408385031215615327576153266150a8565b5b5f615334858286016150f2565b9250506020615345858286016150f2565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6153836014836151c6565b915061538e8261534f565b602082019050919050565b5f6020820190508181035f8301526153b081615377565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f6153eb6016836151c6565b91506153f6826153b7565b602082019050919050565b5f6020820190508181035f830152615418816153df565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61545682615106565b915061546183615106565b92508282039050818111156154795761547861541f565b5b92915050565b5f61548982615106565b915061549483615106565b92508282019050808211156154ac576154ab61541f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806154f657607f821691505b602082108103615509576155086154b2565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6155436001836151c6565b915061554e8261550f565b602082019050919050565b5f6020820190508181035f83015261557081615537565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6155ab6001836151c6565b91506155b682615577565b602082019050919050565b5f6020820190508181035f8301526155d88161559f565b905091905056fea26469706673582212206fbf384dcd110eb4456b07e83a2c8a392433c7852a66dec9f8ebf3989cad1f6764736f6c634300081e0033", } // ContractABI is the input ABI used to generate the binding from. @@ -2217,130 +2217,6 @@ func (_Contract *ContractCallerSession) Dummy65() (*big.Int, error) { return _Contract.Contract.Dummy65(&_Contract.CallOpts) } -// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. -// -// Solidity: function dummy66() pure returns(uint256) -func (_Contract *ContractCaller) Dummy66(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy66") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. -// -// Solidity: function dummy66() pure returns(uint256) -func (_Contract *ContractSession) Dummy66() (*big.Int, error) { - return _Contract.Contract.Dummy66(&_Contract.CallOpts) -} - -// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. -// -// Solidity: function dummy66() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy66() (*big.Int, error) { - return _Contract.Contract.Dummy66(&_Contract.CallOpts) -} - -// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. -// -// Solidity: function dummy67() pure returns(uint256) -func (_Contract *ContractCaller) Dummy67(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy67") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. -// -// Solidity: function dummy67() pure returns(uint256) -func (_Contract *ContractSession) Dummy67() (*big.Int, error) { - return _Contract.Contract.Dummy67(&_Contract.CallOpts) -} - -// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. -// -// Solidity: function dummy67() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy67() (*big.Int, error) { - return _Contract.Contract.Dummy67(&_Contract.CallOpts) -} - -// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. -// -// Solidity: function dummy68() pure returns(uint256) -func (_Contract *ContractCaller) Dummy68(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy68") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. -// -// Solidity: function dummy68() pure returns(uint256) -func (_Contract *ContractSession) Dummy68() (*big.Int, error) { - return _Contract.Contract.Dummy68(&_Contract.CallOpts) -} - -// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. -// -// Solidity: function dummy68() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy68() (*big.Int, error) { - return _Contract.Contract.Dummy68(&_Contract.CallOpts) -} - -// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. -// -// Solidity: function dummy69() pure returns(uint256) -func (_Contract *ContractCaller) Dummy69(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy69") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. -// -// Solidity: function dummy69() pure returns(uint256) -func (_Contract *ContractSession) Dummy69() (*big.Int, error) { - return _Contract.Contract.Dummy69(&_Contract.CallOpts) -} - -// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. -// -// Solidity: function dummy69() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy69() (*big.Int, error) { - return _Contract.Contract.Dummy69(&_Contract.CallOpts) -} - // Dummy7 is a free data retrieval call binding the contract method 0xf26c779b. // // Solidity: function dummy7() pure returns(uint256) @@ -2372,192 +2248,6 @@ func (_Contract *ContractCallerSession) Dummy7() (*big.Int, error) { return _Contract.Contract.Dummy7(&_Contract.CallOpts) } -// Dummy70 is a free data retrieval call binding the contract method 0xbbe23132. -// -// Solidity: function dummy70() pure returns(uint256) -func (_Contract *ContractCaller) Dummy70(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy70") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy70 is a free data retrieval call binding the contract method 0xbbe23132. -// -// Solidity: function dummy70() pure returns(uint256) -func (_Contract *ContractSession) Dummy70() (*big.Int, error) { - return _Contract.Contract.Dummy70(&_Contract.CallOpts) -} - -// Dummy70 is a free data retrieval call binding the contract method 0xbbe23132. -// -// Solidity: function dummy70() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy70() (*big.Int, error) { - return _Contract.Contract.Dummy70(&_Contract.CallOpts) -} - -// Dummy71 is a free data retrieval call binding the contract method 0xf4978b04. -// -// Solidity: function dummy71() pure returns(uint256) -func (_Contract *ContractCaller) Dummy71(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy71") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy71 is a free data retrieval call binding the contract method 0xf4978b04. -// -// Solidity: function dummy71() pure returns(uint256) -func (_Contract *ContractSession) Dummy71() (*big.Int, error) { - return _Contract.Contract.Dummy71(&_Contract.CallOpts) -} - -// Dummy71 is a free data retrieval call binding the contract method 0xf4978b04. -// -// Solidity: function dummy71() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy71() (*big.Int, error) { - return _Contract.Contract.Dummy71(&_Contract.CallOpts) -} - -// Dummy72 is a free data retrieval call binding the contract method 0x1f29783f. -// -// Solidity: function dummy72() pure returns(uint256) -func (_Contract *ContractCaller) Dummy72(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy72") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy72 is a free data retrieval call binding the contract method 0x1f29783f. -// -// Solidity: function dummy72() pure returns(uint256) -func (_Contract *ContractSession) Dummy72() (*big.Int, error) { - return _Contract.Contract.Dummy72(&_Contract.CallOpts) -} - -// Dummy72 is a free data retrieval call binding the contract method 0x1f29783f. -// -// Solidity: function dummy72() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy72() (*big.Int, error) { - return _Contract.Contract.Dummy72(&_Contract.CallOpts) -} - -// Dummy73 is a free data retrieval call binding the contract method 0x595471b8. -// -// Solidity: function dummy73() pure returns(uint256) -func (_Contract *ContractCaller) Dummy73(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy73") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy73 is a free data retrieval call binding the contract method 0x595471b8. -// -// Solidity: function dummy73() pure returns(uint256) -func (_Contract *ContractSession) Dummy73() (*big.Int, error) { - return _Contract.Contract.Dummy73(&_Contract.CallOpts) -} - -// Dummy73 is a free data retrieval call binding the contract method 0x595471b8. -// -// Solidity: function dummy73() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy73() (*big.Int, error) { - return _Contract.Contract.Dummy73(&_Contract.CallOpts) -} - -// Dummy74 is a free data retrieval call binding the contract method 0xb4c48668. -// -// Solidity: function dummy74() pure returns(uint256) -func (_Contract *ContractCaller) Dummy74(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy74") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy74 is a free data retrieval call binding the contract method 0xb4c48668. -// -// Solidity: function dummy74() pure returns(uint256) -func (_Contract *ContractSession) Dummy74() (*big.Int, error) { - return _Contract.Contract.Dummy74(&_Contract.CallOpts) -} - -// Dummy74 is a free data retrieval call binding the contract method 0xb4c48668. -// -// Solidity: function dummy74() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy74() (*big.Int, error) { - return _Contract.Contract.Dummy74(&_Contract.CallOpts) -} - -// Dummy75 is a free data retrieval call binding the contract method 0x378c5382. -// -// Solidity: function dummy75() pure returns(uint256) -func (_Contract *ContractCaller) Dummy75(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy75") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Dummy75 is a free data retrieval call binding the contract method 0x378c5382. -// -// Solidity: function dummy75() pure returns(uint256) -func (_Contract *ContractSession) Dummy75() (*big.Int, error) { - return _Contract.Contract.Dummy75(&_Contract.CallOpts) -} - -// Dummy75 is a free data retrieval call binding the contract method 0x378c5382. -// -// Solidity: function dummy75() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy75() (*big.Int, error) { - return _Contract.Contract.Dummy75(&_Contract.CallOpts) -} - // Dummy8 is a free data retrieval call binding the contract method 0x19cf6a91. // // Solidity: function dummy8() pure returns(uint256) diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol index 29fe7221..4fb9e66d 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol @@ -318,46 +318,6 @@ contract StateBloatToken { return 65; } - function dummy66() public pure returns (uint256) { - return 66; - } - - function dummy67() public pure returns (uint256) { - return 67; - } - - function dummy68() public pure returns (uint256) { - return 68; - } - - function dummy69() public pure returns (uint256) { - return 69; - } - - function dummy70() public pure returns (uint256) { - return 70; - } - - function dummy71() public pure returns (uint256) { - return 71; - } - - function dummy72() public pure returns (uint256) { - return 72; - } - - function dummy73() public pure returns (uint256) { - return 73; - } - - function dummy74() public pure returns (uint256) { - return 74; - } - - function dummy75() public pure returns (uint256) { - return 75; - } - function transferFrom1( address from, address to, From 3132162b5f6762ec654a972c18d49bad74fc3c08 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sat, 7 Jun 2025 12:43:44 +0200 Subject: [PATCH 20/39] feat(contract-deploy): improve bytecode size ratio & auto-adapt to gas_limit - Introduced BlockDeploymentStats struct to track deployment statistics per block, including contract count, total gas used, and total bytecode size. - Implemented real-time block monitoring for logging deployment summaries. - Updated contract bytecode size calculations to reflect actual deployed bytecode. - Adjusted transaction processing intervals for improved efficiency. --- .../contract/StateBloatToken.bin | 2 +- .../contract/StateBloatToken.sol | 21 ++ .../contract_deploy/contract_deploy.go | 245 +++++++++++++++--- 3 files changed, 230 insertions(+), 38 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin index 7d363997..755497f1 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin @@ -1 +1 @@ -60a060405234801561000f575f5ffd5b50604051615d6a380380615d6a833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b6080516156156107555f395f61482101526156155ff3fe608060405234801561000f575f5ffd5b5060043610610518575f3560e01c8063657b6ef7116102a2578063aaa7af7011610170578063d7419469116100d7578063f26c779b11610090578063f26c779b1461110a578063f5f5738114611128578063f8716f1414611146578063faf35ced14611164578063fe7d599614611194578063ffbf0469146111b257610518565b8063d741946914611032578063dc1d8a9b14611050578063dd62ed3e1461106e578063e2d275301461109e578063e8c927b3146110bc578063eb4329c8146110da57610518565b8063bb9bfe0611610129578063bb9bfe0614610f5a578063bfa0b13314610f8a578063c2be97e314610fa8578063c958d4bf14610fd8578063cfd6686314610ff6578063d101dcd01461101457610518565b8063aaa7af7014610e82578063acc5aee914610ea0578063ad8f422114610ed0578063b1802b9a14610eee578063b2bb360e14610f1e578063b66dd75014610f3c57610518565b80637c72ed0d116102145780638f4a8406116101cd5780638f4a840614610dbc57806395d89b4114610dda5780639c5dfe7314610df85780639df61a2514610e16578063a891d4d414610e34578063a9059cbb14610e5257610518565b80637c72ed0d14610cf65780637dffdc3214610d145780637e54493714610d325780637f34d94b14610d505780638619d60714610d6e5780638789ca6714610d8c57610518565b806374e73fd31161026657806374e73fd314610c3057806374f83d0214610c4e57806377c0209e14610c6c578063792c7f3e14610c8a5780637a319c1814610ca85780637c66673e14610cc657610518565b8063657b6ef714610b64578063672151fe14610b945780636abceacd14610bb25780636c12ed2814610bd057806370a0823114610c0057610518565b80633125f37a116103ea5780634a2e93c611610351578063552a1b561161030a578063552a1b5614610a9e57806358b6a9bd14610ace5780635af92c0514610aec57806361b970eb14610b0a578063639ec53a14610b285780636547317414610b4657610518565b80634a2e93c6146109d85780634b3c7f5f146109f65780634e1dbb8214610a145780634f5e555714610a325780634f7bd75a14610a5057806354c2792014610a8057610518565b80633ea117ce116103a35780633ea117ce146109125780634128a85d14610930578063418b18161461094e57806342937dbd1461096c57806343a6b92d1461098a57806344050a28146109a857610518565b80633125f37a1461083a578063313ce5671461085857806334517f0b1461087657806339e0bd12146108945780633a131990146108c45780633b6be459146108f457610518565b80631a97f18e1161048e5780631fd298ec116104475780631fd298ec1461076257806321ecd7a314610780578063239af2a51461079e57806323b872dd146107bc5780632545d8b7146107ec578063291c3bd71461080a57610518565b80631a97f18e1461068a5780631b17c65c146106a85780631bbffe6f146106d85780631d527cde146107085780631eaa7c52146107265780631f4495891461074457610518565b80631215a3ab116104e05780631215a3ab146105d657806312901b42146105f457806313ebb5ec1461061257806316a3045b1461063057806318160ddd1461064e57806319cf6a911461066c57610518565b80630460faf61461051c57806306fdde031461054c5780630717b1611461056a578063095ea7b3146105885780630cb7a9e7146105b8575b5f5ffd5b61053660048036038101906105319190615139565b6111d0565b60405161054391906151a3565b60405180910390f35b6105546114b0565b604051610561919061522c565b60405180910390f35b61057261153b565b60405161057f919061525b565b60405180910390f35b6105a2600480360381019061059d9190615274565b611543565b6040516105af91906151a3565b60405180910390f35b6105c0611630565b6040516105cd919061525b565b60405180910390f35b6105de611638565b6040516105eb919061525b565b60405180910390f35b6105fc611640565b604051610609919061525b565b60405180910390f35b61061a611648565b604051610627919061525b565b60405180910390f35b610638611650565b604051610645919061525b565b60405180910390f35b610656611658565b604051610663919061525b565b60405180910390f35b61067461165e565b604051610681919061525b565b60405180910390f35b610692611666565b60405161069f919061525b565b60405180910390f35b6106c260048036038101906106bd9190615139565b61166e565b6040516106cf91906151a3565b60405180910390f35b6106f260048036038101906106ed9190615139565b61194e565b6040516106ff91906151a3565b60405180910390f35b610710611c2e565b60405161071d919061525b565b60405180910390f35b61072e611c36565b60405161073b919061525b565b60405180910390f35b61074c611c3e565b604051610759919061525b565b60405180910390f35b61076a611c46565b604051610777919061525b565b60405180910390f35b610788611c4e565b604051610795919061525b565b60405180910390f35b6107a6611c56565b6040516107b3919061525b565b60405180910390f35b6107d660048036038101906107d19190615139565b611c5e565b6040516107e391906151a3565b60405180910390f35b6107f4611f3e565b604051610801919061525b565b60405180910390f35b610824600480360381019061081f9190615139565b611f46565b60405161083191906151a3565b60405180910390f35b610842612226565b60405161084f919061525b565b60405180910390f35b61086061222e565b60405161086d91906152cd565b60405180910390f35b61087e612240565b60405161088b919061525b565b60405180910390f35b6108ae60048036038101906108a99190615139565b612248565b6040516108bb91906151a3565b60405180910390f35b6108de60048036038101906108d99190615139565b612528565b6040516108eb91906151a3565b60405180910390f35b6108fc612808565b604051610909919061525b565b60405180910390f35b61091a612810565b604051610927919061525b565b60405180910390f35b610938612818565b604051610945919061525b565b60405180910390f35b610956612820565b604051610963919061525b565b60405180910390f35b610974612828565b604051610981919061525b565b60405180910390f35b610992612830565b60405161099f919061525b565b60405180910390f35b6109c260048036038101906109bd9190615139565b612838565b6040516109cf91906151a3565b60405180910390f35b6109e0612b18565b6040516109ed919061525b565b60405180910390f35b6109fe612b20565b604051610a0b919061525b565b60405180910390f35b610a1c612b28565b604051610a29919061525b565b60405180910390f35b610a3a612b30565b604051610a47919061525b565b60405180910390f35b610a6a6004803603810190610a659190615139565b612b38565b604051610a7791906151a3565b60405180910390f35b610a88612e18565b604051610a95919061525b565b60405180910390f35b610ab86004803603810190610ab39190615139565b612e20565b604051610ac591906151a3565b60405180910390f35b610ad6613100565b604051610ae3919061525b565b60405180910390f35b610af4613108565b604051610b01919061525b565b60405180910390f35b610b12613110565b604051610b1f919061525b565b60405180910390f35b610b30613118565b604051610b3d919061525b565b60405180910390f35b610b4e613120565b604051610b5b919061525b565b60405180910390f35b610b7e6004803603810190610b799190615139565b613128565b604051610b8b91906151a3565b60405180910390f35b610b9c613408565b604051610ba9919061525b565b60405180910390f35b610bba613410565b604051610bc7919061525b565b60405180910390f35b610bea6004803603810190610be59190615139565b613418565b604051610bf791906151a3565b60405180910390f35b610c1a6004803603810190610c1591906152e6565b6136f8565b604051610c27919061525b565b60405180910390f35b610c3861370d565b604051610c45919061525b565b60405180910390f35b610c56613715565b604051610c63919061525b565b60405180910390f35b610c7461371d565b604051610c81919061525b565b60405180910390f35b610c92613725565b604051610c9f919061525b565b60405180910390f35b610cb061372d565b604051610cbd919061525b565b60405180910390f35b610ce06004803603810190610cdb9190615139565b613735565b604051610ced91906151a3565b60405180910390f35b610cfe613a15565b604051610d0b919061525b565b60405180910390f35b610d1c613a1d565b604051610d29919061525b565b60405180910390f35b610d3a613a25565b604051610d47919061525b565b60405180910390f35b610d58613a2d565b604051610d65919061525b565b60405180910390f35b610d76613a35565b604051610d83919061525b565b60405180910390f35b610da66004803603810190610da19190615139565b613a3d565b604051610db391906151a3565b60405180910390f35b610dc4613d1d565b604051610dd1919061525b565b60405180910390f35b610de2613d25565b604051610def919061522c565b60405180910390f35b610e00613db1565b604051610e0d919061525b565b60405180910390f35b610e1e613db9565b604051610e2b919061525b565b60405180910390f35b610e3c613dc1565b604051610e49919061525b565b60405180910390f35b610e6c6004803603810190610e679190615274565b613dc9565b604051610e7991906151a3565b60405180910390f35b610e8a613f5f565b604051610e97919061525b565b60405180910390f35b610eba6004803603810190610eb59190615139565b613f67565b604051610ec791906151a3565b60405180910390f35b610ed8614247565b604051610ee5919061525b565b60405180910390f35b610f086004803603810190610f039190615139565b61424f565b604051610f1591906151a3565b60405180910390f35b610f2661452f565b604051610f33919061525b565b60405180910390f35b610f44614537565b604051610f51919061525b565b60405180910390f35b610f746004803603810190610f6f9190615139565b61453f565b604051610f8191906151a3565b60405180910390f35b610f9261481f565b604051610f9f919061525b565b60405180910390f35b610fc26004803603810190610fbd9190615139565b614843565b604051610fcf91906151a3565b60405180910390f35b610fe0614b23565b604051610fed919061525b565b60405180910390f35b610ffe614b2b565b60405161100b919061525b565b60405180910390f35b61101c614b33565b604051611029919061525b565b60405180910390f35b61103a614b3b565b604051611047919061525b565b60405180910390f35b611058614b43565b604051611065919061525b565b60405180910390f35b61108860048036038101906110839190615311565b614b4b565b604051611095919061525b565b60405180910390f35b6110a6614b6b565b6040516110b3919061525b565b60405180910390f35b6110c4614b73565b6040516110d1919061525b565b60405180910390f35b6110f460048036038101906110ef9190615139565b614b7b565b60405161110191906151a3565b60405180910390f35b611112614da0565b60405161111f919061525b565b60405180910390f35b611130614da8565b60405161113d919061525b565b60405180910390f35b61114e614db0565b60405161115b919061525b565b60405180910390f35b61117e60048036038101906111799190615139565b614db8565b60405161118b91906151a3565b60405180910390f35b61119c615098565b6040516111a9919061525b565b60405180910390f35b6111ba6150a0565b6040516111c7919061525b565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124890615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561130c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130390615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611358919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546113ab919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611439919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161149d919061525b565b60405180910390a3600190509392505050565b5f80546114bc906154df565b80601f01602080910402602001604051908101604052809291908181526020018280546114e8906154df565b80156115335780601f1061150a57610100808354040283529160200191611533565b820191905f5260205f20905b81548152906001019060200180831161151657829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161161e919061525b565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156116ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156117aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546117f6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611849919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546118d7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161193b919061525b565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156119cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611a8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ad6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611b29919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611bb7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c1b919061525b565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611d9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611de6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611e39919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ec7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611f2b919061525b565b60405180910390a3600190509392505050565b5f6001905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611fc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fbe90615559565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612082576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612079906155c1565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546120ce919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612121919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546121af919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612213919061525b565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546123d0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612423919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546124b1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612515919061525b565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156125a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125a090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546126b0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612703919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612791919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516127f5919061525b565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156128b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161296b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546129c0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612a13919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612aa1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b05919061525b565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612bb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c6b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612cc0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612d13919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612da1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612e05919061525b565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ea1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9890615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612f5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5390615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612fa8919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ffb919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613089919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130ed919061525b565b60405180910390a3600190509392505050565b5f6009905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156131a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a090615559565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161325b906155c1565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546132b0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613303919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613391919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516133f5919061525b565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613499576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161354b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135a0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135f3919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613681919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516136e5919061525b565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156137b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137ad90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161386890615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546138bd919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613910919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461399e919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613a02919061525b565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613abe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ab590615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613b79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b7090615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613bc5919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613c18919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ca6919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613d0a919061525b565b60405180910390a3600190509392505050565b5f600b905090565b60018054613d32906154df565b80601f0160208091040260200160405190810160405280929190818152602001828054613d5e906154df565b8015613da95780601f10613d8057610100808354040283529160200191613da9565b820191905f5260205f20905b815481529060010190602001808311613d8c57829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613e4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e4190615399565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e96919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ee9919061547f565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613f4d919061525b565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613fe8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fdf90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156140a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161409a90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546140ef919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614142919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546141d0919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614234919061525b565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156142d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016142c790615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561438b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161438290615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546143d7919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461442a919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546144b8919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161451c919061525b565b60405180910390a3600190509392505050565b5f6018905090565b5f600f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156145c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016145b790615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561467b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161467290615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146c7919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461471a919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546147a8919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161480c919061525b565b60405180910390a3600190509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156148c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148bb90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561497f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161497690615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546149cb919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614a1e919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614aac919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614b10919061525b565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614bfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614bf390615559565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c48919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c9b919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d29919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614d8d919061525b565b60405180910390a3600190509392505050565b5f6007905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614e39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614e3090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614ef4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614eeb90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f40919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f93919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254615021919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051615085919061525b565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6150d5826150ac565b9050919050565b6150e5816150cb565b81146150ef575f5ffd5b50565b5f81359050615100816150dc565b92915050565b5f819050919050565b61511881615106565b8114615122575f5ffd5b50565b5f813590506151338161510f565b92915050565b5f5f5f606084860312156151505761514f6150a8565b5b5f61515d868287016150f2565b935050602061516e868287016150f2565b925050604061517f86828701615125565b9150509250925092565b5f8115159050919050565b61519d81615189565b82525050565b5f6020820190506151b65f830184615194565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6151fe826151bc565b61520881856151c6565b93506152188185602086016151d6565b615221816151e4565b840191505092915050565b5f6020820190508181035f83015261524481846151f4565b905092915050565b61525581615106565b82525050565b5f60208201905061526e5f83018461524c565b92915050565b5f5f6040838503121561528a576152896150a8565b5b5f615297858286016150f2565b92505060206152a885828601615125565b9150509250929050565b5f60ff82169050919050565b6152c7816152b2565b82525050565b5f6020820190506152e05f8301846152be565b92915050565b5f602082840312156152fb576152fa6150a8565b5b5f615308848285016150f2565b91505092915050565b5f5f60408385031215615327576153266150a8565b5b5f615334858286016150f2565b9250506020615345858286016150f2565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6153836014836151c6565b915061538e8261534f565b602082019050919050565b5f6020820190508181035f8301526153b081615377565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f6153eb6016836151c6565b91506153f6826153b7565b602082019050919050565b5f6020820190508181035f830152615418816153df565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61545682615106565b915061546183615106565b92508282039050818111156154795761547861541f565b5b92915050565b5f61548982615106565b915061549483615106565b92508282019050808211156154ac576154ab61541f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806154f657607f821691505b602082108103615509576155086154b2565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6155436001836151c6565b915061554e8261550f565b602082019050919050565b5f6020820190508181035f83015261557081615537565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6155ab6001836151c6565b91506155b682615577565b602082019050919050565b5f6020820190508181035f8301526155d88161559f565b905091905056fea26469706673582212206fbf384dcd110eb4456b07e83a2c8a392433c7852a66dec9f8ebf3989cad1f6764736f6c634300081e0033 \ No newline at end of file +60a060405234801561000f575f5ffd5b50604051615fba380380615fba833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b6080516158656107555f395f61493601526158655ff3fe608060405234801561000f575f5ffd5b506004361061057f575f3560e01c8063657b6ef7116102e3578063ad8f42211161018b578063d9bb3174116100f2578063ee1682b6116100ab578063f8716f1411610085578063f8716f1414611243578063faf35ced14611261578063fe7d599614611291578063ffbf0469146112af5761057f565b8063ee1682b6146111e9578063f26c779b14611207578063f5f57381146112255761057f565b8063d9bb317414611111578063dc1d8a9b1461112f578063dd62ed3e1461114d578063e2d275301461117d578063e8c927b31461119b578063eb4329c8146111b95761057f565b8063bfa0b13311610144578063bfa0b1331461104b578063c2be97e314611069578063c958d4bf14611099578063cfd66863146110b7578063d101dcd0146110d5578063d7419469146110f35761057f565b8063ad8f422114610f73578063b1802b9a14610f91578063b2bb360e14610fc1578063b66dd75014610fdf578063b9a6d64514610ffd578063bb9bfe061461101b5761057f565b80637dffdc321161024a57806395d89b4111610203578063a891d4d4116101dd578063a891d4d414610ed7578063a9059cbb14610ef5578063aaa7af7014610f25578063acc5aee914610f435761057f565b806395d89b4114610e7d5780639c5dfe7314610e9b5780639df61a2514610eb95761057f565b80637dffdc3214610db75780637e54493714610dd55780637f34d94b14610df35780638619d60714610e115780638789ca6714610e2f5780638f4a840614610e5f5761057f565b806374f83d021161029c57806374f83d0214610cf157806377c0209e14610d0f578063792c7f3e14610d2d5780637a319c1814610d4b5780637c66673e14610d695780637c72ed0d14610d995761057f565b8063657b6ef714610c07578063672151fe14610c375780636abceacd14610c555780636c12ed2814610c7357806370a0823114610ca357806374e73fd314610cd35761057f565b80633125f37a116104465780634a2e93c6116103ad578063552a1b561161036657806361b970eb1161034057806361b970eb14610b8f578063639ec53a14610bad5780636547317414610bcb5780636578534c14610be95761057f565b8063552a1b5614610b2357806358b6a9bd14610b535780635af92c0514610b715761057f565b80634a2e93c614610a5d5780634b3c7f5f14610a7b5780634e1dbb8214610a995780634f5e555714610ab75780634f7bd75a14610ad557806354c2792014610b055761057f565b80633ea117ce116103ff5780633ea117ce146109975780634128a85d146109b5578063418b1816146109d357806342937dbd146109f157806343a6b92d14610a0f57806344050a2814610a2d5761057f565b80633125f37a146108bf578063313ce567146108dd57806334517f0b146108fb57806339e0bd12146109195780633a131990146109495780633b6be459146109795761057f565b80631b17c65c116104ea57806321ecd7a3116104a357806321ecd7a3146107e7578063239af2a51461080557806323b872dd146108235780632545d8b7146108535780632787325b14610871578063291c3bd71461088f5761057f565b80631b17c65c1461070f5780631bbffe6f1461073f5780631d527cde1461076f5780631eaa7c521461078d5780631f449589146107ab5780631fd298ec146107c95761057f565b806312901b421161053c57806312901b421461065b57806313ebb5ec1461067957806316a3045b1461069757806318160ddd146106b557806319cf6a91146106d35780631a97f18e146106f15761057f565b80630460faf61461058357806306fdde03146105b35780630717b161146105d1578063095ea7b3146105ef5780630cb7a9e71461061f5780631215a3ab1461063d575b5f5ffd5b61059d60048036038101906105989190615275565b6112cd565b6040516105aa91906152df565b60405180910390f35b6105bb6115ad565b6040516105c89190615368565b60405180910390f35b6105d9611638565b6040516105e69190615397565b60405180910390f35b610609600480360381019061060491906153b0565b611640565b60405161061691906152df565b60405180910390f35b61062761172d565b6040516106349190615397565b60405180910390f35b610645611735565b6040516106529190615397565b60405180910390f35b61066361173d565b6040516106709190615397565b60405180910390f35b610681611745565b60405161068e9190615397565b60405180910390f35b61069f61174d565b6040516106ac9190615397565b60405180910390f35b6106bd611755565b6040516106ca9190615397565b60405180910390f35b6106db61175b565b6040516106e89190615397565b60405180910390f35b6106f9611763565b6040516107069190615397565b60405180910390f35b61072960048036038101906107249190615275565b61176b565b60405161073691906152df565b60405180910390f35b61075960048036038101906107549190615275565b611a4b565b60405161076691906152df565b60405180910390f35b610777611d2b565b6040516107849190615397565b60405180910390f35b610795611d33565b6040516107a29190615397565b60405180910390f35b6107b3611d3b565b6040516107c09190615397565b60405180910390f35b6107d1611d43565b6040516107de9190615397565b60405180910390f35b6107ef611d4b565b6040516107fc9190615397565b60405180910390f35b61080d611d53565b60405161081a9190615397565b60405180910390f35b61083d60048036038101906108389190615275565b611d5b565b60405161084a91906152df565b60405180910390f35b61085b61203b565b6040516108689190615397565b60405180910390f35b610879612043565b6040516108869190615397565b60405180910390f35b6108a960048036038101906108a49190615275565b61204b565b6040516108b691906152df565b60405180910390f35b6108c761232b565b6040516108d49190615397565b60405180910390f35b6108e5612333565b6040516108f29190615409565b60405180910390f35b610903612345565b6040516109109190615397565b60405180910390f35b610933600480360381019061092e9190615275565b61234d565b60405161094091906152df565b60405180910390f35b610963600480360381019061095e9190615275565b61262d565b60405161097091906152df565b60405180910390f35b61098161290d565b60405161098e9190615397565b60405180910390f35b61099f612915565b6040516109ac9190615397565b60405180910390f35b6109bd61291d565b6040516109ca9190615397565b60405180910390f35b6109db612925565b6040516109e89190615397565b60405180910390f35b6109f961292d565b604051610a069190615397565b60405180910390f35b610a17612935565b604051610a249190615397565b60405180910390f35b610a476004803603810190610a429190615275565b61293d565b604051610a5491906152df565b60405180910390f35b610a65612c1d565b604051610a729190615397565b60405180910390f35b610a83612c25565b604051610a909190615397565b60405180910390f35b610aa1612c2d565b604051610aae9190615397565b60405180910390f35b610abf612c35565b604051610acc9190615397565b60405180910390f35b610aef6004803603810190610aea9190615275565b612c3d565b604051610afc91906152df565b60405180910390f35b610b0d612f1d565b604051610b1a9190615397565b60405180910390f35b610b3d6004803603810190610b389190615275565b612f25565b604051610b4a91906152df565b60405180910390f35b610b5b613205565b604051610b689190615397565b60405180910390f35b610b7961320d565b604051610b869190615397565b60405180910390f35b610b97613215565b604051610ba49190615397565b60405180910390f35b610bb561321d565b604051610bc29190615397565b60405180910390f35b610bd3613225565b604051610be09190615397565b60405180910390f35b610bf161322d565b604051610bfe9190615397565b60405180910390f35b610c216004803603810190610c1c9190615275565b613235565b604051610c2e91906152df565b60405180910390f35b610c3f613515565b604051610c4c9190615397565b60405180910390f35b610c5d61351d565b604051610c6a9190615397565b60405180910390f35b610c8d6004803603810190610c889190615275565b613525565b604051610c9a91906152df565b60405180910390f35b610cbd6004803603810190610cb89190615422565b613805565b604051610cca9190615397565b60405180910390f35b610cdb61381a565b604051610ce89190615397565b60405180910390f35b610cf9613822565b604051610d069190615397565b60405180910390f35b610d1761382a565b604051610d249190615397565b60405180910390f35b610d35613832565b604051610d429190615397565b60405180910390f35b610d5361383a565b604051610d609190615397565b60405180910390f35b610d836004803603810190610d7e9190615275565b613842565b604051610d9091906152df565b60405180910390f35b610da1613b22565b604051610dae9190615397565b60405180910390f35b610dbf613b2a565b604051610dcc9190615397565b60405180910390f35b610ddd613b32565b604051610dea9190615397565b60405180910390f35b610dfb613b3a565b604051610e089190615397565b60405180910390f35b610e19613b42565b604051610e269190615397565b60405180910390f35b610e496004803603810190610e449190615275565b613b4a565b604051610e5691906152df565b60405180910390f35b610e67613e2a565b604051610e749190615397565b60405180910390f35b610e85613e32565b604051610e929190615368565b60405180910390f35b610ea3613ebe565b604051610eb09190615397565b60405180910390f35b610ec1613ec6565b604051610ece9190615397565b60405180910390f35b610edf613ece565b604051610eec9190615397565b60405180910390f35b610f0f6004803603810190610f0a91906153b0565b613ed6565b604051610f1c91906152df565b60405180910390f35b610f2d61406c565b604051610f3a9190615397565b60405180910390f35b610f5d6004803603810190610f589190615275565b614074565b604051610f6a91906152df565b60405180910390f35b610f7b614354565b604051610f889190615397565b60405180910390f35b610fab6004803603810190610fa69190615275565b61435c565b604051610fb891906152df565b60405180910390f35b610fc961463c565b604051610fd69190615397565b60405180910390f35b610fe7614644565b604051610ff49190615397565b60405180910390f35b61100561464c565b6040516110129190615397565b60405180910390f35b61103560048036038101906110309190615275565b614654565b60405161104291906152df565b60405180910390f35b611053614934565b6040516110609190615397565b60405180910390f35b611083600480360381019061107e9190615275565b614958565b60405161109091906152df565b60405180910390f35b6110a1614c38565b6040516110ae9190615397565b60405180910390f35b6110bf614c40565b6040516110cc9190615397565b60405180910390f35b6110dd614c48565b6040516110ea9190615397565b60405180910390f35b6110fb614c50565b6040516111089190615397565b60405180910390f35b611119614c58565b6040516111269190615397565b60405180910390f35b611137614c60565b6040516111449190615397565b60405180910390f35b6111676004803603810190611162919061544d565b614c68565b6040516111749190615397565b60405180910390f35b611185614c88565b6040516111929190615397565b60405180910390f35b6111a3614c90565b6040516111b09190615397565b60405180910390f35b6111d360048036038101906111ce9190615275565b614c98565b6040516111e091906152df565b60405180910390f35b6111f1614ebd565b6040516111fe9190615368565b60405180910390f35b61120f614edc565b60405161121c9190615397565b60405180910390f35b61122d614ee4565b60405161123a9190615397565b60405180910390f35b61124b614eec565b6040516112589190615397565b60405180910390f35b61127b60048036038101906112769190615275565b614ef4565b60405161128891906152df565b60405180910390f35b6112996151d4565b6040516112a69190615397565b60405180910390f35b6112b76151dc565b6040516112c49190615397565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561134e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611345906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611409576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114009061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546114559190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546114a891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546115369190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161159a9190615397565b60405180910390a3600190509392505050565b5f80546115b99061561b565b80601f01602080910402602001604051908101604052809291908181526020018280546115e59061561b565b80156116305780601f1061160757610100808354040283529160200191611630565b820191905f5260205f20905b81548152906001019060200180831161161357829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161171b9190615397565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156117ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e3906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156118a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189e9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546118f39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461194691906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546119d49190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611a389190615397565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611acc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac3906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611b87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7e9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611bd39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611c2691906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611cb49190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611d189190615397565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611ddc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd3906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611e97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e8e9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ee39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611f3691906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611fc49190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516120289190615397565b60405180910390a3600190509392505050565b5f6001905090565b5f6045905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156120cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c390615695565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217e906156fd565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546121d39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461222691906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546122b49190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516123189190615397565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156123ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c5906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612489576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124809061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546124d59190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461252891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546125b69190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161261a9190615397565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156126ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a5906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612769576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127609061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546127b59190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461280891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546128969190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516128fa9190615397565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156129be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b5906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612a79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a709061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ac59190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612b1891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ba69190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612c0a9190615397565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612cbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cb5906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612d79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d709061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612dc59190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612e1891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ea69190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612f0a9190615397565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612fa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f9d906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613061576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130589061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546130ad9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461310091906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461318e9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131f29190615397565b60405180910390a3600190509392505050565b5f6009905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f6043905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156132b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ad90615695565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613368906156fd565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546133bd9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461341091906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461349e9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516135029190615397565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156135a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161359d906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613661576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136589061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546136ad9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461370091906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461378e9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516137f29190615397565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156138c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138ba906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561397e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139759061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546139ca9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613a1d91906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613aab9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613b0f9190615397565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613bcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613bc2906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c7d9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613cd29190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613d2591906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613db39190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613e179190615397565b60405180910390a3600190509392505050565b5f600b905090565b60018054613e3f9061561b565b80601f0160208091040260200160405190810160405280929190818152602001828054613e6b9061561b565b8015613eb65780601f10613e8d57610100808354040283529160200191613eb6565b820191905f5260205f20905b815481529060010190602001808311613e9957829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613f57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613f4e906154d5565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613fa39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ff691906155bb565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161405a9190615397565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156140f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016140ec906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156141b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016141a79061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546141fc9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461424f91906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546142dd9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516143419190615397565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156143dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016143d4906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161448f9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546144e49190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461453791906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546145c59190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516146299190615397565b60405180910390a3600190509392505050565b5f6018905090565b5f600f905090565b5f6044905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156146d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016146cc906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614790576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016147879061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546147dc9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461482f91906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546148bd9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516149219190615397565b60405180910390a3600190509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156149d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016149d0906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614a94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614a8b9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614ae09190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614b3391906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614bc19190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614c259190615397565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6042905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614d19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614d1090615695565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d659190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614db891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614e469190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614eaa9190615397565b60405180910390a3600190509392505050565b604051806101400160405280610114815260200161571c610114913981565b5f6007905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614f75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614f6c906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015615030576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016150279061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461507c9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546150cf91906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461515d9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516151c19190615397565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f615211826151e8565b9050919050565b61522181615207565b811461522b575f5ffd5b50565b5f8135905061523c81615218565b92915050565b5f819050919050565b61525481615242565b811461525e575f5ffd5b50565b5f8135905061526f8161524b565b92915050565b5f5f5f6060848603121561528c5761528b6151e4565b5b5f6152998682870161522e565b93505060206152aa8682870161522e565b92505060406152bb86828701615261565b9150509250925092565b5f8115159050919050565b6152d9816152c5565b82525050565b5f6020820190506152f25f8301846152d0565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61533a826152f8565b6153448185615302565b9350615354818560208601615312565b61535d81615320565b840191505092915050565b5f6020820190508181035f8301526153808184615330565b905092915050565b61539181615242565b82525050565b5f6020820190506153aa5f830184615388565b92915050565b5f5f604083850312156153c6576153c56151e4565b5b5f6153d38582860161522e565b92505060206153e485828601615261565b9150509250929050565b5f60ff82169050919050565b615403816153ee565b82525050565b5f60208201905061541c5f8301846153fa565b92915050565b5f60208284031215615437576154366151e4565b5b5f6154448482850161522e565b91505092915050565b5f5f60408385031215615463576154626151e4565b5b5f6154708582860161522e565b92505060206154818582860161522e565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6154bf601483615302565b91506154ca8261548b565b602082019050919050565b5f6020820190508181035f8301526154ec816154b3565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f615527601683615302565b9150615532826154f3565b602082019050919050565b5f6020820190508181035f8301526155548161551b565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61559282615242565b915061559d83615242565b92508282039050818111156155b5576155b461555b565b5b92915050565b5f6155c582615242565b91506155d083615242565b92508282019050808211156155e8576155e761555b565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061563257607f821691505b602082108103615645576156446155ee565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f61567f600183615302565b915061568a8261564b565b602082019050919050565b5f6020820190508181035f8301526156ac81615673565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6156e7600183615302565b91506156f2826156b3565b602082019050919050565b5f6020820190508181035f830152615714816156db565b905091905056fe414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141a26469706673582212203e477b8749988ccd0a67b1a6d43c11976c00a420dbe43a9f84158e8962430d7664736f6c634300081e0033 \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol index 4fb9e66d..eb7dc2dc 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.sol @@ -12,6 +12,10 @@ contract StateBloatToken { // Salt to make each deployment unique uint256 public immutable salt; + // Large constant to increase bytecode size to exactly 24KiB + string public constant PADDING_DATA = + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, @@ -318,6 +322,23 @@ contract StateBloatToken { return 65; } + // Additional dummy functions to increase bytecode to exactly 24KiB + function dummy66() public pure returns (uint256) { + return 66; + } + + function dummy67() public pure returns (uint256) { + return 67; + } + + function dummy68() public pure returns (uint256) { + return 68; + } + + function dummy69() public pure returns (uint256) { + return 69; + } + function transferFrom1( address from, address to, diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index cc7e80af..4e8948b1 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -48,6 +48,14 @@ type PendingTransaction struct { PrivateKey *ecdsa.PrivateKey } +// BlockDeploymentStats tracks deployment statistics per block +type BlockDeploymentStats struct { + BlockNumber uint64 + ContractCount int + TotalGasUsed uint64 + TotalBytecodeSize int +} + type Scenario struct { options ScenarioOptions logger *logrus.Entry @@ -65,12 +73,21 @@ type Scenario struct { // Results tracking deployedContracts []ContractDeployment contractsMutex sync.Mutex + + // Block-level statistics tracking + blockStats map[uint64]*BlockDeploymentStats + blockStatsMutex sync.Mutex + lastLoggedBlock uint64 + + // Block monitoring for real-time logging + blockMonitorCancel context.CancelFunc + blockMonitorDone chan struct{} } var ScenarioName = "contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ MaxPending: 10, - MaxWallets: 0, + MaxWallets: 1000, BaseFee: 20, TipFee: 2, ClientGroup: "default", @@ -93,10 +110,10 @@ func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.MaxPending, "max-pending", ScenarioDefaultOptions.MaxPending, "Maximum number of pending transactions") flags.Uint64Var(&s.options.MaxWallets, "max-wallets", ScenarioDefaultOptions.MaxWallets, "Maximum number of child wallets to use") - flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Max fee per gas to use in transactions (in gwei)") - flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") + flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Base fee per gas in gwei") + flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Tip fee per gas in gwei") flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") - flags.Uint64Var(&s.options.MaxTransactions, "max-transactions", ScenarioDefaultOptions.MaxTransactions, "Maximum number of transactions to send (0 for unlimited)") + flags.Uint64Var(&s.options.MaxTransactions, "max-transactions", ScenarioDefaultOptions.MaxTransactions, "Maximum number of transactions to send (0 = use rate limiting based on block gas limit)") return nil } @@ -112,6 +129,8 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { if s.options.MaxWallets > 0 { walletPool.SetWalletCount(s.options.MaxWallets) + } else if s.options.MaxTransactions == 0 { + walletPool.SetWalletCount(1) } else { walletPool.SetWalletCount(1000) } @@ -150,7 +169,7 @@ func (s *Scenario) waitForPendingTxSlot(ctx context.Context) { // Check and clean up confirmed transactions s.processPendingTransactions(ctx) - time.Sleep(500 * time.Millisecond) + time.Sleep(1 * time.Second) } } @@ -224,35 +243,54 @@ func (s *Scenario) recordDeployedContract(contractAddress common.Address, privat s.deployedContracts = append(s.deployedContracts, deployment) - // Calculate detailed information for logging - walletAddress := crypto.PubkeyToAddress(privateKey.PublicKey) - - // Get the actual transaction to calculate real bytecode size + // Get the actual deployed contract bytecode size client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) - var bytecodeSize int = 24564 // Default fallback - var gasPerByte float64 + // TODO: This should be a constant documented on how this number is obtained. + var bytecodeSize int = 23914 if client != nil { - tx, _, err := client.GetEthClient().TransactionByHash(context.Background(), txHash) + // Get the actual deployed bytecode size using eth_getCode + contractCode, err := client.GetEthClient().CodeAt(context.Background(), contractAddress, nil) if err == nil { - bytecodeSize = len(tx.Data()) + bytecodeSize = len(contractCode) + } + } + + blockNumber := receipt.BlockNumber.Uint64() + + // Debug logging for block tracking + s.logger.WithFields(logrus.Fields{ + "tx_block": blockNumber, + "existing_blocks": len(s.blockStats), + }).Debug("Recording contract deployment") + + // Update block-level statistics + s.blockStatsMutex.Lock() + defer s.blockStatsMutex.Unlock() + + if s.blockStats == nil { + s.blockStats = make(map[uint64]*BlockDeploymentStats) + } + + // Create or update current block stats (removed the old logging logic) + if s.blockStats[blockNumber] == nil { + s.blockStats[blockNumber] = &BlockDeploymentStats{ + BlockNumber: blockNumber, } + s.logger.WithField("block_number", blockNumber).Debug("Created new block stats") } - // Calculate gas per byte - gasPerByte = float64(receipt.GasUsed) / float64(max(bytecodeSize, 1)) + blockStat := s.blockStats[blockNumber] + blockStat.ContractCount++ + blockStat.TotalGasUsed += receipt.GasUsed + blockStat.TotalBytecodeSize += bytecodeSize - // Log with detailed information s.logger.WithFields(logrus.Fields{ - "block_number": receipt.BlockNumber.Uint64(), - "bytecode_size": bytecodeSize, - "contract_address": deployment.ContractAddress, - "gas_per_byte": fmt.Sprintf("%.2f", gasPerByte), - "gas_used": receipt.GasUsed, - "total_contracts": len(s.deployedContracts), - "tx_hash": txHash.Hex(), - "wallet_address": walletAddress.Hex(), - }).Info("Contract successfully deployed and recorded") + "block_number": blockNumber, + "contracts_in_block": blockStat.ContractCount, + "gas_used": blockStat.TotalGasUsed, + "bytecode_size": blockStat.TotalBytecodeSize, + }).Debug("Updated block stats") // Save the deployments.json file each time a contract is confirmed if err := s.saveDeploymentsMapping(); err != nil { @@ -297,10 +335,86 @@ func (s *Scenario) saveDeploymentsMapping() error { return nil } +// startBlockMonitor starts a background goroutine that monitors for new blocks +// and logs block deployment summaries immediately when blocks are mined +func (s *Scenario) startBlockMonitor(ctx context.Context) { + monitorCtx, cancel := context.WithCancel(ctx) + s.blockMonitorCancel = cancel + s.blockMonitorDone = make(chan struct{}) + + go func() { + defer close(s.blockMonitorDone) + + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) + if client == nil { + s.logger.Warn("No client available for block monitoring") + return + } + + ethClient := client.GetEthClient() + ticker := time.NewTicker(2 * time.Second) // Poll every 2 seconds + defer ticker.Stop() + + for { + select { + case <-monitorCtx.Done(): + return + case <-ticker.C: + // Get current block number + latestBlock, err := ethClient.BlockByNumber(monitorCtx, nil) + if err != nil { + s.logger.WithError(err).Debug("Failed to get latest block for monitoring") + continue + } + + currentBlockNumber := latestBlock.Number().Uint64() + + // Log any completed blocks that haven't been logged yet + s.blockStatsMutex.Lock() + for bn := s.lastLoggedBlock + 1; bn < currentBlockNumber; bn++ { + if stats, exists := s.blockStats[bn]; exists && stats.ContractCount > 0 { + avgGasPerByte := float64(stats.TotalGasUsed) / float64(max(stats.TotalBytecodeSize, 1)) + + s.contractsMutex.Lock() + totalContracts := len(s.deployedContracts) + s.contractsMutex.Unlock() + + s.logger.WithFields(logrus.Fields{ + "block_number": bn, + "contracts_deployed": stats.ContractCount, + "total_gas_used": stats.TotalGasUsed, + "total_bytecode_size": stats.TotalBytecodeSize, + "avg_gas_per_byte": fmt.Sprintf("%.2f", avgGasPerByte), + "total_contracts": totalContracts, + }).Info("Block deployment summary") + + s.lastLoggedBlock = bn + } + } + s.blockStatsMutex.Unlock() + } + } + }() +} + +// stopBlockMonitor stops the block monitoring goroutine +func (s *Scenario) stopBlockMonitor() { + if s.blockMonitorCancel != nil { + s.blockMonitorCancel() + } + if s.blockMonitorDone != nil { + <-s.blockMonitorDone // Wait for goroutine to finish + } +} + func (s *Scenario) Run(ctx context.Context) error { s.logger.Infof("starting scenario: %s", ScenarioName) defer s.logger.Infof("scenario %s finished.", ScenarioName) + // Start block monitoring for real-time logging + s.startBlockMonitor(ctx) + defer s.stopBlockMonitor() + // Cache chain ID at startup chainID, err := s.getChainID(ctx) if err != nil { @@ -309,16 +423,59 @@ func (s *Scenario) Run(ctx context.Context) error { s.logger.Infof("Chain ID: %s", chainID.String()) + // Calculate rate limiting based on block gas limit if max-transactions is 0 + var maxTxsPerBlock uint64 + var useRateLimiting bool + + if s.options.MaxTransactions == 0 { + // Get block gas limit from the network + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) + if client == nil { + return fmt.Errorf("no client available for gas limit query") + } + + latestBlock, err := client.GetEthClient().BlockByNumber(ctx, nil) + if err != nil { + return fmt.Errorf("failed to get latest block: %w", err) + } + + blockGasLimit := latestBlock.GasLimit() + // TODO: This should be a constant. + estimatedGasPerContract := uint64(4949468) // Updated estimate based on contract size reduction + maxTxsPerBlock = blockGasLimit / estimatedGasPerContract + useRateLimiting = true + + s.logger.Infof("Rate limiting enabled: block gas limit %d, gas per contract %d, max txs per block %d", + blockGasLimit, estimatedGasPerContract, maxTxsPerBlock) + } + txIdxCounter := uint64(0) totalTxCount := atomic.Uint64{} + blockTxCount := uint64(0) + lastBlockTime := time.Now() for { - // Check if we've reached max transactions + // Check if we've reached max transactions (if set) if s.options.MaxTransactions > 0 && txIdxCounter >= s.options.MaxTransactions { s.logger.Infof("reached maximum number of transactions (%d)", s.options.MaxTransactions) break } + // Rate limiting logic + if useRateLimiting { + // If we've sent maxTxsPerBlock transactions, wait for next block interval + if blockTxCount >= maxTxsPerBlock { + timeSinceLastBlock := time.Since(lastBlockTime) + if timeSinceLastBlock < 12*time.Second { // Assume ~12 second block time + sleepTime := 12*time.Second - timeSinceLastBlock + s.logger.Infof("Rate limit reached (%d txs), waiting %v for next block", maxTxsPerBlock, sleepTime) + time.Sleep(sleepTime) + } + blockTxCount = 0 + lastBlockTime = time.Now() + } + } + // Wait for available slot s.waitForPendingTxSlot(ctx) @@ -332,8 +489,9 @@ func (s *Scenario) Run(ctx context.Context) error { txIdxCounter++ totalTxCount.Add(1) + blockTxCount++ - // Process pending transactions periodically + // Process pending transactions periodically with 1 second intervals if txIdxCounter%10 == 0 { s.processPendingTransactions(ctx) @@ -348,7 +506,7 @@ func (s *Scenario) Run(ctx context.Context) error { time.Sleep(100 * time.Millisecond) } - // Wait for all pending transactions to complete + // Wait for all pending transactions to complete with 1 second intervals s.logger.Info("Waiting for remaining transactions to complete...") for { s.processPendingTransactions(ctx) @@ -362,8 +520,29 @@ func (s *Scenario) Run(ctx context.Context) error { } s.logger.Infof("Waiting for %d pending transactions...", pendingCount) - time.Sleep(2 * time.Second) + time.Sleep(1 * time.Second) // Changed from 2 seconds to 1 second + } + + // Stop block monitoring before final cleanup + s.stopBlockMonitor() + + // Log any remaining unlogged blocks (final blocks) - keep this as final safety net + s.blockStatsMutex.Lock() + for bn, stats := range s.blockStats { + if bn > s.lastLoggedBlock && stats.ContractCount > 0 { + avgGasPerByte := float64(stats.TotalGasUsed) / float64(max(stats.TotalBytecodeSize, 1)) + + s.logger.WithFields(logrus.Fields{ + "block_number": bn, + "contracts_deployed": stats.ContractCount, + "total_gas_used": stats.TotalGasUsed, + "total_bytecode_size": stats.TotalBytecodeSize, + "avg_gas_per_byte": fmt.Sprintf("%.2f", avgGasPerByte), + "total_contracts": len(s.deployedContracts), + }).Info("Block deployment summary") + } } + s.blockStatsMutex.Unlock() // Log final summary s.contractsMutex.Lock() @@ -527,13 +706,5 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, attempt s.pendingTxs[tx.Hash()] = pendingTx s.pendingTxsMutex.Unlock() - s.logger.WithFields(logrus.Fields{ - "tx_hash": tx.Hash().Hex(), - "nonce": nonce, - "base_fee_gwei": s.options.BaseFee, - "tip_fee_gwei": s.options.TipFee, - "attempt": attempt + 1, - }).Info("Transaction sent") - return nil } From 94fc7640dc4b7056a1e26e33002fca9852120bbf Mon Sep 17 00:00:00 2001 From: CPerezz Date: Fri, 13 Jun 2025 01:13:09 +0200 Subject: [PATCH 21/39] feat(contract-deploy): improve transaction handling with timestamp and timeout logic --- .../statebloat/contract_deploy/README.md | 9 ++-- .../contract_deploy/contract_deploy.go | 45 ++++++++++--------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/README.md b/scenarios/statebloat/contract_deploy/README.md index 204e3dfe..26b2f56b 100644 --- a/scenarios/statebloat/contract_deploy/README.md +++ b/scenarios/statebloat/contract_deploy/README.md @@ -45,15 +45,14 @@ go build -o bin/spamoor cmd/spamoor/main.go ``` #### Key Flags -- `--max-transactions` - Number of contracts to deploy (0 = infinite, default: 0) -- `--max-pending` - Max concurrent pending transactions (default: 10) -- `--max-wallets` - Max child wallets to use (default: 1000) -- `--basefee` - Base fee per gas in gwei (default: 20) +- `--max-transactions` - Total number of contracts to deploy (0 = infinite, default: 0) +- `--max-wallets` - Max child wallets to use (0 = root wallet only, default: 0) +- `--basefee` - Base fee per gas in gwei (default: 10) - `--tipfee` - Tip fee per gas in gwei (default: 2) #### Example with Anvil node ```bash ./bin/spamoor --privkey ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ --rpchost http://localhost:8545 contract-deploy \ - --max-transactions 100 --max-pending 20 --basefee 25 --tipfee 5 + --max-transactions 0 ``` \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 4e8948b1..d2018956 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -46,6 +46,7 @@ type ContractDeployment struct { type PendingTransaction struct { TxHash common.Hash PrivateKey *ecdsa.PrivateKey + Timestamp time.Time } // BlockDeploymentStats tracks deployment statistics per block @@ -86,11 +87,9 @@ type Scenario struct { var ScenarioName = "contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ - MaxPending: 10, - MaxWallets: 1000, - BaseFee: 20, - TipFee: 2, - ClientGroup: "default", + MaxWallets: 0, // Use root wallet only by default + BaseFee: 5, // Moderate base fee (5 gwei) + TipFee: 1, // Priority fee (1 gwei) MaxTransactions: 0, } var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ @@ -129,10 +128,10 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { if s.options.MaxWallets > 0 { walletPool.SetWalletCount(s.options.MaxWallets) - } else if s.options.MaxTransactions == 0 { - walletPool.SetWalletCount(1) } else { - walletPool.SetWalletCount(1000) + // Use only root wallet by default for better efficiency + // This avoids child wallet funding overhead + walletPool.SetWalletCount(0) } return nil @@ -185,6 +184,7 @@ func (s *Scenario) processPendingTransactions(ctx context.Context) { ethClient := client.GetEthClient() var confirmedTxs []common.Hash + var timedOutTxs []common.Hash var successfulDeployments []struct { ContractAddress common.Address PrivateKey *ecdsa.PrivateKey @@ -193,6 +193,13 @@ func (s *Scenario) processPendingTransactions(ctx context.Context) { } for txHash, pendingTx := range s.pendingTxs { + // Check if transaction is too old (1 minute timeout) + if time.Since(pendingTx.Timestamp) > 1*time.Minute { + s.logger.Warnf("Transaction %s timed out after 1 minute, removing from pending", txHash.Hex()) + timedOutTxs = append(timedOutTxs, txHash) + continue + } + receipt, err := ethClient.TransactionReceipt(ctx, txHash) if err != nil { // Transaction still pending or error retrieving receipt @@ -222,6 +229,11 @@ func (s *Scenario) processPendingTransactions(ctx context.Context) { delete(s.pendingTxs, txHash) } + // Remove timed out transactions from pending map + for _, txHash := range timedOutTxs { + delete(s.pendingTxs, txHash) + } + s.pendingTxsMutex.Unlock() // Process successful deployments after releasing the lock @@ -607,15 +619,7 @@ func (s *Scenario) updateDynamicFees(ctx context.Context) error { // Convert base fee from wei to gwei currentBaseFeeGwei := new(big.Int).Div(latestBlock.BaseFee(), big.NewInt(1000000000)) - // Set new base fee to current base fee + 20% buffer - newBaseFeeGwei := new(big.Int).Mul(currentBaseFeeGwei, big.NewInt(120)) - newBaseFeeGwei = new(big.Int).Div(newBaseFeeGwei, big.NewInt(100)) - - // Ensure minimum increase of 5 gwei - minIncrease := big.NewInt(5) - if newBaseFeeGwei.Cmp(new(big.Int).Add(big.NewInt(int64(s.options.BaseFee)), minIncrease)) < 0 { - newBaseFeeGwei = new(big.Int).Add(big.NewInt(int64(s.options.BaseFee)), minIncrease) - } + newBaseFeeGwei := new(big.Int).Add(currentBaseFeeGwei, big.NewInt(100)) s.options.BaseFee = newBaseFeeGwei.Uint64() @@ -623,7 +627,7 @@ func (s *Scenario) updateDynamicFees(ctx context.Context) error { if s.options.TipFee+1 > 3 { s.options.TipFee = s.options.TipFee + 1 } else { - s.options.TipFee = 3 // Minimum 3 gwei tip + s.options.TipFee = 2 // Minimum 3 gwei tip } s.logger.Infof("Updated dynamic fees - Base fee: %d gwei, Tip fee: %d gwei (network base fee: %s gwei)", @@ -636,8 +640,8 @@ func (s *Scenario) updateDynamicFees(ctx context.Context) error { // attemptTransaction makes a single attempt to send a transaction func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, attempt int) error { // Get client and wallet - client := s.walletPool.GetClient(spamoor.SelectClientRoundRobin, 0, s.options.ClientGroup) - wallet := s.walletPool.GetWallet(spamoor.SelectWalletRoundRobin, 0) + client := s.walletPool.GetClient(spamoor.SelectClientRoundRobin, 0, "") + wallet := s.walletPool.GetRootWallet() if client == nil { return fmt.Errorf("no client available") @@ -700,6 +704,7 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, attempt pendingTx := &PendingTransaction{ TxHash: tx.Hash(), PrivateKey: wallet.GetPrivateKey(), + Timestamp: time.Now(), } s.pendingTxsMutex.Lock() From 139b18e0430de25cc7d83e145a047199143808e5 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 18 Jun 2025 11:17:06 +0200 Subject: [PATCH 22/39] chore: gitignore update to remoive .bin & .abi --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 998622c1..a10d2501 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ bin spamoor.db* go.lib.mod go.lib.sum +*.abi +*.bin From 2b21a1111893615f91ab219026e7a3c849a4dc07 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 11 Jun 2025 00:57:55 +0200 Subject: [PATCH 23/39] add(eao-delegation): Create eoa-delegation scenario oriented to bloating Revert the changes done to the original `setcodetx`. - Move the bloating code to `eoa-delegation` under statebloat. --- scenarios/scenarios.go | 7 + scenarios/statebloat/eoa_delegation/README.md | 79 ++ .../eoa_delegation/eoa_delegation.go | 1167 +++++++++++++++++ 3 files changed, 1253 insertions(+) create mode 100644 scenarios/statebloat/eoa_delegation/README.md create mode 100644 scenarios/statebloat/eoa_delegation/eoa_delegation.go diff --git a/scenarios/scenarios.go b/scenarios/scenarios.go index e0f32a82..d5a6a9a7 100644 --- a/scenarios/scenarios.go +++ b/scenarios/scenarios.go @@ -13,6 +13,10 @@ import ( "github.com/ethpandaops/spamoor/scenarios/erctx" "github.com/ethpandaops/spamoor/scenarios/gasburnertx" "github.com/ethpandaops/spamoor/scenarios/setcodetx" + contractdeploy "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy" + eoadelegation "github.com/ethpandaops/spamoor/scenarios/statebloat/eoa_delegation" + + //extcodesizeoverload "github.com/ethpandaops/spamoor/scenarios/statebloat/extcodesize_overload" uniswapswaps "github.com/ethpandaops/spamoor/scenarios/uniswap-swaps" "github.com/ethpandaops/spamoor/scenarios/wallets" ) @@ -30,6 +34,9 @@ var ScenarioDescriptors = []*scenariotypes.ScenarioDescriptor{ &setcodetx.ScenarioDescriptor, &uniswapswaps.ScenarioDescriptor, &wallets.ScenarioDescriptor, + &contractdeploy.ScenarioDescriptor, + &eoadelegation.ScenarioDescriptor, + //&extcodesizeoverload.ScenarioDescriptor, } func GetScenario(name string) *scenariotypes.ScenarioDescriptor { diff --git a/scenarios/statebloat/eoa_delegation/README.md b/scenarios/statebloat/eoa_delegation/README.md new file mode 100644 index 00000000..0a4f5a60 --- /dev/null +++ b/scenarios/statebloat/eoa_delegation/README.md @@ -0,0 +1,79 @@ +# EOA Delegation Scenario + +## Overview + +The EOA Delegation scenario is designed for maximum state bloating through EIP-7702 SetCode transactions. It creates the largest possible state growth by delegating thousands of Externally Owned Accounts (EOAs) to existing contracts in a single block. + +This scenario is a specialized stress-testing tool that: +- Automatically adjusts to fill 99.5% of block gas limit +- Funds EOAs with 1 wei each before delegation +- Tracks all funded EOAs in `EOAs.json` for future reference +- Handles transaction size limits by batching when necessary +- Continuously operates in a loop, creating maximum state growth + +## How It Works + +### Three-Phase Operation + +1. **Funding Phase**: Pre-funds delegator EOAs with 1 wei each +2. **Bloating Phase**: Sends SetCode transaction(s) with maximum authorizations +3. **Analysis Phase**: Measures performance and adjusts parameters + +### Key Features + +- **Self-Adjusting**: Dynamically adjusts authorization count based on actual gas usage +- **Network-Aware**: Queries actual block gas limit from the network +- **Size-Aware**: Automatically splits large transactions that exceed 128KiB limit +- **Persistent Storage**: Saves all funded EOAs to `EOAs.json` for reuse + +### Technical Details + +- Each EOA delegation creates ~135 bytes of new state +- Uses ecrecover precompile (0x1) as default delegation target +- Targets 99.5% block utilization for maximum impact +- Handles up to ~1300 authorizations per 128KiB RLP-encoded transaction +- Transaction size limit: 128KiB (131,072 bytes) applies to the RLP-encoded transaction +- Actual authorization size in transaction: ~94 bytes per authorization (RLP-encoded) + +## Usage + +### Basic Usage + +```bash +# Run with default settings (auto-adjusts to network) +# Address is set to Identity precompile by default. +eoa-delegation -h -p + +# Specify custom delegation target +eoa-delegation eoa-delegation --code-addr 0x1234567890123456789012345678901234567890 + +# Control gas prices +eoa-delegation eoa-delegation --basefee 30 --tipfee 3 +``` + +### Command Line Options + +- `--code-addr`: Contract address to delegate to (default: ecrecover precompile) +- `--basefee`: Base fee in gwei (default: 20) +- `--tipfee`: Priority fee in gwei (default: 2) +- `--client-group`: Specific client group to use +- `--rebroadcast`: Seconds between transaction rebroadcasts (default: 120) + +### Output + +The scenario logs detailed metrics for each iteration: + +``` +STATE BLOATING METRICS - Total bytes written: 130.5 KiB, Gas used: 25.2M, Block utilization: 98.7%, Authorizations: 990, Gas/auth: 25454.5, Gas/byte: 188.6, Total fee: 0.0504 ETH +``` + +## State Impact + +This scenario creates maximum state growth by: +1. Creating new EOA accounts (funded with 1 wei) +2. Adding delegation records for each EOA +3. Updating nonce and balance for each account + +## Files Created + +- `EOAs.json`: Contains addresses and private keys of all funded EOAs diff --git a/scenarios/statebloat/eoa_delegation/eoa_delegation.go b/scenarios/statebloat/eoa_delegation/eoa_delegation.go new file mode 100644 index 00000000..8f6cf269 --- /dev/null +++ b/scenarios/statebloat/eoa_delegation/eoa_delegation.go @@ -0,0 +1,1167 @@ +package eoadelegation + +import ( + "context" + "crypto/sha256" + "encoding/binary" + "encoding/json" + "fmt" + "math/big" + "os" + "strings" + "sync" + "sync/atomic" + "time" + + "gopkg.in/yaml.v3" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/holiman/uint256" + "github.com/sirupsen/logrus" + "github.com/spf13/pflag" + + "github.com/ethpandaops/spamoor/scenariotypes" + "github.com/ethpandaops/spamoor/spamoor" + "github.com/ethpandaops/spamoor/txbuilder" +) + +// EIP-7702 gas cost constants +const ( + // PER_AUTH_BASE_COST (EIP-7702) - upper bound on gas cost per authorization when delegating to existing contract in this scenario + GasPerAuthorization = 26000 + // EstimatedBytesPerAuth - estimated state change in bytes per EOA delegation + EstimatedBytesPerAuth = 135.0 + // ActualBytesPerAuth - actual observed RLP-encoded bytes per authorization in transaction + // RLP encoding breakdown for typical authorization: + // - ChainID: ~3 bytes (RLP encodes integers efficiently, not fixed 8 bytes) + // - Address: 21 bytes (0x94 prefix + 20 bytes) + // - Nonce: 1 byte (0x80 for nonce 0, small values) + // - YParity: 1 byte (0x00 or 0x01) + // - R: 33 bytes (0xa0 prefix + 32 bytes) + // - S: 33 bytes (0xa0 prefix + 32 bytes) + // - List overhead: 2 bytes (0xf8 + length byte) + // Total: ~94 bytes (confirmed by empirical data: 89KiB for 969 auths) + ActualBytesPerAuth = 94 + // DefaultTargetGasRatio - target percentage of block gas limit to use (99.5% for minimal safety margin) + DefaultTargetGasRatio = 0.995 + // FallbackBlockGasLimit - fallback gas limit if network query fails + FallbackBlockGasLimit = 30000000 + // BaseTransferCost - gas cost for a standard ETH transfer + BaseTransferCost = 21000 + // MaxTransactionSize - Ethereum transaction size limit in bytes (128KiB) + MaxTransactionSize = 131072 // 128 * 1024 + // GweiPerEth - conversion factor from Gwei to Wei + GweiPerEth = 1000000000 + // BlockMiningTimeout - timeout for waiting for a new block to be mined + BlockMiningTimeout = 30 * time.Second + // BlockPollingInterval - interval for checking new blocks + BlockPollingInterval = 1 * time.Second + // MaxRebroadcasts - maximum number of times to rebroadcast a transaction + MaxRebroadcasts = 10 + // TransactionBatchSize - used for batching funding transactions + TransactionBatchSize = 100 + // TransactionBatchThreshold - threshold for continuing to fill a block + TransactionBatchThreshold = 50 + // InitialTransactionDelay - delay between initial funding transactions + InitialTransactionDelay = 10 * time.Millisecond + // OptimizedTransactionDelay - reduced delay after initial batch + OptimizedTransactionDelay = 5 * time.Millisecond + // FundingConfirmationDelay - delay before checking funding confirmations + FundingConfirmationDelay = 3 * time.Second + // RetryDelay - delay before retrying failed operations + RetryDelay = 5 * time.Second + // FundingIterationOffset - large offset to avoid delegator index conflicts between iterations + FundingIterationOffset = 1000000 + // TransactionBaseOverhead - base RLP encoding overhead for a transaction + TransactionBaseOverhead = 200 + // TransactionExtraOverhead - additional RLP encoding overhead + TransactionExtraOverhead = 50 + // GasPerCallDataByte - gas cost per byte of calldata (16 gas per non-zero byte) + GasPerCallDataByte = 16 + // BytesPerKiB - bytes in a kibibyte + BytesPerKiB = 1024.0 + // GasPerMillion - divisor for converting gas to millions + GasPerMillion = 1_000_000.0 + // TransactionSizeSafetyFactor - safety factor for transaction size (95%) + TransactionSizeSafetyFactor = 95 +) + +type ScenarioOptions struct { + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` + CodeAddr string `yaml:"code_addr"` +} + +// EOAEntry represents a funded EOA account +type EOAEntry struct { + Address string `json:"address"` + PrivateKey string `json:"private_key"` +} + +type Scenario struct { + options ScenarioOptions + logger *logrus.Entry + walletPool *spamoor.WalletPool + + // FIFO queue for funded accounts + eoaQueue []EOAEntry + eoaQueueMutex sync.Mutex + + // Semaphore for worker control + workerSemaphore chan struct{} + workerDone chan struct{} + workerWg sync.WaitGroup +} + +var ScenarioName = "eoa-delegation" +var ScenarioDefaultOptions = ScenarioOptions{ + BaseFee: 20, + TipFee: 2, + CodeAddr: "", +} +var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ + Name: ScenarioName, + Description: "Maximum state bloating via EIP-7702 EOA delegations", + DefaultOptions: ScenarioDefaultOptions, + NewScenario: newScenario, +} + +func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { + return &Scenario{ + logger: logger.WithField("scenario", ScenarioName), + } +} + +func (s *Scenario) Flags(flags *pflag.FlagSet) error { + flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Max fee per gas to use in transactions (in gwei)") + flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") + flags.StringVar(&s.options.CodeAddr, "code-addr", ScenarioDefaultOptions.CodeAddr, "Code delegation target address to use for transactions (default: ecrecover precompile)") + return nil +} + +func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { + s.walletPool = walletPool + + if config != "" { + err := yaml.Unmarshal([]byte(config), &s.options) + if err != nil { + return fmt.Errorf("failed to unmarshal config: %w", err) + } + } + + if s.options.CodeAddr == "" { + s.logger.Infof("no --code-addr specified, using ecrecover precompile as delegate: %s", common.HexToAddress("0x0000000000000000000000000000000000000001")) + } + + // In max-bloating mode, use 1 wallet (the root wallet) + s.walletPool.SetWalletCount(1) + + // Initialize FIFO queue and worker for EOA management + s.eoaQueue = make([]EOAEntry, 0) + s.workerSemaphore = make(chan struct{}, 1) // Buffered channel for semaphore + s.workerDone = make(chan struct{}) + + // Start the worker goroutine for writing EOAs to file + s.workerWg.Add(1) + go s.eoaWorker() + + return nil +} + +func (s *Scenario) Config() string { + yamlBytes, _ := yaml.Marshal(&s.options) + return string(yamlBytes) +} + +// getNetworkBlockGasLimit retrieves the current block gas limit from the network +// It waits for a new block to be mined (with timeout) to ensure fresh data +func (s *Scenario) getNetworkBlockGasLimit(ctx context.Context, client *txbuilder.Client) uint64 { + // Create a timeout context for the entire operation + timeoutCtx, cancel := context.WithTimeout(ctx, BlockMiningTimeout) + defer cancel() + + // Get the current block number first + currentBlockNumber, err := client.GetEthClient().BlockNumber(timeoutCtx) + if err != nil { + s.logger.Warnf("failed to get current block number: %v, using fallback: %d", err, FallbackBlockGasLimit) + return FallbackBlockGasLimit + } + + s.logger.Debugf("waiting for new block to be mined (current: %d, timeout: %v)", currentBlockNumber, BlockMiningTimeout) + + // Wait for a new block to be mined + ticker := time.NewTicker(BlockPollingInterval) + defer ticker.Stop() + + var latestBlock *types.Block + for { + select { + case <-timeoutCtx.Done(): + s.logger.Warnf("timeout waiting for new block to be mined, using fallback: %d", FallbackBlockGasLimit) + return FallbackBlockGasLimit + case <-ticker.C: + // Check for a new block + newBlockNumber, err := client.GetEthClient().BlockNumber(timeoutCtx) + if err != nil { + s.logger.Debugf("error checking block number: %v", err) + continue + } + + // If we have a new block, get its details + if newBlockNumber > currentBlockNumber { + latestBlock, err = client.GetEthClient().BlockByNumber(timeoutCtx, nil) + if err != nil { + s.logger.Debugf("error getting latest block details: %v", err) + continue + } + s.logger.Debugf("new block mined: %d", newBlockNumber) + goto blockFound + } + } + } + +blockFound: + gasLimit := latestBlock.GasLimit() + s.logger.Debugf("network block gas limit from fresh block #%d: %d", latestBlock.NumberU64(), gasLimit) + return gasLimit +} + +func (s *Scenario) Run(ctx context.Context) error { + // This scenario only runs in max-bloating mode + return s.runMaxBloatingMode(ctx) +} + +func (s *Scenario) prepareDelegator(delegatorIndex uint64) (*txbuilder.Wallet, error) { + idxBytes := make([]byte, 8) + binary.BigEndian.PutUint64(idxBytes, delegatorIndex) + childKey := sha256.Sum256(append(common.FromHex(s.walletPool.GetRootWallet().GetAddress().Hex()), idxBytes...)) + return txbuilder.NewWallet(fmt.Sprintf("%x", childKey)) +} + +func (s *Scenario) buildMaxBloatingAuthorizations(targetCount int, iteration int) []types.SetCodeAuthorization { + authorizations := make([]types.SetCodeAuthorization, 0, targetCount) + + // Use a fixed delegate contract address for maximum efficiency + // In max bloating mode, we want all EOAs to delegate to the same existing contract + // to benefit from reduced gas costs (PER_AUTH_BASE_COST vs PER_EMPTY_ACCOUNT_COST) + // Precompiles are ideal as they're guaranteed to exist with code on all networks + var codeAddr common.Address + if s.options.CodeAddr != "" { + codeAddr = common.HexToAddress(s.options.CodeAddr) + } else { + // Default to using the ecrecover precompile (0x1) as delegate target + codeAddr = common.HexToAddress("0x0000000000000000000000000000000000000001") + } + + chainId := s.walletPool.GetRootWallet().GetChainId().Uint64() + + for i := 0; i < targetCount; i++ { + // Create a unique delegator for each authorization + // Include iteration counter to ensure different addresses for each iteration + delegatorIndex := uint64(iteration*targetCount + i) + + delegator, err := s.prepareDelegator(delegatorIndex) + if err != nil { + s.logger.Errorf("could not prepare delegator %v: %v", delegatorIndex, err) + continue + } + + // Each EOA uses auth_nonce = 0 (assuming first EIP-7702 operation) + // This creates maximum new state as each EOA gets its first delegation + authorization := types.SetCodeAuthorization{ + ChainID: *uint256.NewInt(chainId), + Address: codeAddr, + Nonce: 0, // First delegation for each EOA + } + + // Sign the authorization with the delegator's private key + signedAuth, err := types.SignSetCode(delegator.GetPrivateKey(), authorization) + if err != nil { + s.logger.Errorf("could not sign set code authorization for delegator %v: %v", delegatorIndex, err) + continue + } + + authorizations = append(authorizations, signedAuth) + } + + return authorizations +} + +func (s *Scenario) runMaxBloatingMode(ctx context.Context) error { + s.logger.Infof("starting max bloating mode: self-adjusting to target block gas limit, continuous operation") + + // Get a client for network operations + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + + // Get the actual network block gas limit + networkGasLimit := s.getNetworkBlockGasLimit(ctx, client) + targetGas := uint64(float64(networkGasLimit) * DefaultTargetGasRatio) + + // Calculate initial authorization count based on network gas limit and known gas cost per authorization + initialAuthorizations := int(targetGas / GasPerAuthorization) + + // Dynamic authorization count - starts based on network parameters and adjusts based on actual performance + currentAuthorizations := initialAuthorizations + + var blockCounter int + + for { + select { + case <-ctx.Done(): + s.logger.Errorf("max bloating mode stopping due to context cancellation") + return ctx.Err() + default: + } + + blockCounter++ + + // For the first iteration, we need to fund delegators before bloating + // For subsequent iterations, funding happens after analysis + if blockCounter == 1 { + s.logger.Infof("════════════════ INITIAL FUNDING PHASE ════════════════") + confirmedCount, err := s.fundMaxBloatingDelegators(ctx, currentAuthorizations, blockCounter, networkGasLimit) + if err != nil { + s.logger.Errorf("failed to fund delegators for initial iteration: %v", err) + time.Sleep(RetryDelay) // Wait before retry + blockCounter-- // Retry the same iteration + continue + } + + // Wait for funding transactions to be confirmed and included in blocks + err = s.waitForFundingConfirmations(ctx, confirmedCount) + if err != nil { + s.logger.Errorf("error waiting for funding confirmations: %v", err) + } + } + + // Send the max bloating transaction and wait for confirmation + s.logger.Infof("════════════════ BLOATING PHASE #%d ════════════════", blockCounter) + actualGasUsed, _, authCount, gasPerAuth, gasPerByte, _, err := s.sendMaxBloatingTransaction(ctx, currentAuthorizations, targetGas, blockCounter) + if err != nil { + s.logger.Errorf("failed to send max bloating transaction for iteration %d: %v", blockCounter, err) + time.Sleep(RetryDelay) // Wait before retry + continue + } + + // Open semaphore (green light) during analysis phase to allow worker to process EOA queue + s.openWorkerSemaphore() + + s.logger.Infof("%%%%%%%%%%%%%%%%%%%% ANALYSIS PHASE #%d %%%%%%%%%%%%%%%%%%%%", blockCounter) + + // Calculate total bytes written to state + totalBytesWritten := authCount * int(EstimatedBytesPerAuth) + + // Get block gas limit for utilization calculation + blockGasLimit := float64(networkGasLimit) + gasUtilization := (float64(actualGasUsed) / blockGasLimit) * 100 + + s.logger.WithField("scenario", "eoa-delegation").Infof("STATE BLOATING METRICS - Total bytes written: %.2f KiB, Gas used: %.2fM, Block utilization: %.2f%%, Authorizations: %d, Gas/auth: %.1f, Gas/byte: %.1f", + float64(totalBytesWritten)/BytesPerKiB, float64(actualGasUsed)/GasPerMillion, gasUtilization, authCount, gasPerAuth, gasPerByte) + + // Self-adjust authorization count based on actual performance + if actualGasUsed > 0 && authCount > 0 { + gasPerAuth := float64(actualGasUsed) / float64(authCount) + targetAuths := int(float64(targetGas) / gasPerAuth) + + // Calculate the adjustment needed + authDifference := targetAuths - authCount + + if actualGasUsed < targetGas { + // We're under target, increase authorization count with a slight safety margin + newAuthorizations := currentAuthorizations + authDifference - 1 + + if newAuthorizations > currentAuthorizations { + s.logger.Infof("Adjusting authorizations: %d → %d (need %d more for target)", + currentAuthorizations, newAuthorizations, authDifference) + currentAuthorizations = newAuthorizations + } + } else if actualGasUsed > targetGas { + // We're over target, reduce to reach max block utilization + excess := actualGasUsed - targetGas + newAuthorizations := currentAuthorizations - int(excess) + 1 + + s.logger.Infof("Reducing authorizations: %d → %d (excess: %d gas)", + currentAuthorizations, newAuthorizations, excess) + currentAuthorizations = newAuthorizations + + } else { + s.logger.Infof("Target achieved! Gas Used: %d / Target: %d", actualGasUsed, targetGas) + } + } + + // Now fund delegators for the next iteration (except on the last iteration) + // This ensures funding happens AFTER bloating transactions are confirmed + s.logger.Infof("════════════════ FUNDING PHASE #%d (for next iteration) ════════════════", blockCounter) + confirmedCount, err := s.fundMaxBloatingDelegators(ctx, currentAuthorizations, blockCounter+1, networkGasLimit) + if err != nil { + s.logger.Errorf("failed to fund delegators for next iteration: %v", err) + // Don't fail the entire loop, just log the error and continue + } + + // Wait for funding transactions to be confirmed before next bloating phase + if confirmedCount > 0 { + err = s.waitForFundingConfirmations(ctx, confirmedCount) + if err != nil { + s.logger.Errorf("error waiting for funding confirmations: %v", err) + } + } + } +} + +func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount int, iteration int, gasLimit uint64) (int64, error) { + // Close semaphore (red light) during funding phase + s.closeWorkerSemaphore() + + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + if client == nil { + return 0, fmt.Errorf("no client available for funding delegators") + } + + // Use root wallet since we set child wallet count to 0 in max-bloating mode + wallet := s.walletPool.GetRootWallet() + + // Get suggested fees for funding transactions + var feeCap *big.Int + var tipCap *big.Int + + if s.options.BaseFee > 0 { + feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(GweiPerEth)) + } + if s.options.TipFee > 0 { + tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(GweiPerEth)) + } + + if feeCap == nil || tipCap == nil { + var err error + feeCap, tipCap, err = client.GetSuggestedFee(s.walletPool.GetContext()) + if err != nil { + return 0, fmt.Errorf("failed to get suggested fees for funding: %w", err) + } + } + + // Minimum gas prices + if feeCap.Cmp(big.NewInt(GweiPerEth)) < 0 { + feeCap = big.NewInt(GweiPerEth) + } + if tipCap.Cmp(big.NewInt(GweiPerEth)) < 0 { + tipCap = big.NewInt(GweiPerEth) + } + + // Fund with 1 wei as requested by user + fundingAmount := uint256.NewInt(1) + + var confirmedCount int64 + sentCount := uint64(0) + delegatorIndex := uint64(iteration * FundingIterationOffset) // Large offset per iteration to avoid conflicts + + // Calculate approximate transactions per block based on gas limit + // Standard transfer = BaseTransferCost gas. + var maxTxsPerBlock = gasLimit / uint64(BaseTransferCost) + + for { + // Check if we have enough confirmed transactions + confirmed := atomic.LoadInt64(&confirmedCount) + if confirmed >= int64(targetCount) { + // We have minimum required, but let's check if we should fill the current block + // If we've sent transactions recently, wait a bit to see if block gets filled + if sentCount > 0 && (sentCount%TransactionBatchSize) > TransactionBatchThreshold { + // Continue to fill the block + } else { + break + } + } + + // Generate unique delegator address + delegator, err := s.prepareDelegator(delegatorIndex) + if err != nil { + s.logger.Errorf("could not prepare delegator %v for funding: %v", delegatorIndex, err) + delegatorIndex++ + continue + } + + // Build funding transaction + delegatorAddr := delegator.GetAddress() + txData, err := txbuilder.DynFeeTx(&txbuilder.TxMetadata{ + GasFeeCap: uint256.MustFromBig(feeCap), + GasTipCap: uint256.MustFromBig(tipCap), + Gas: BaseTransferCost, // Standard ETH transfer gas + To: &delegatorAddr, + Value: fundingAmount, + Data: []byte{}, + }) + if err != nil { + s.logger.Errorf("failed to build funding tx for delegator %d: %v", delegatorIndex, err) + delegatorIndex++ + continue + } + + tx, err := wallet.BuildDynamicFeeTx(txData) + if err != nil { + s.logger.Errorf("failed to build funding transaction for delegator %d: %v", delegatorIndex, err) + delegatorIndex++ + continue + } + + // Send funding transaction with no retries to avoid duplicates + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &txbuilder.SendTransactionOptions{ + Client: client, + MaxRebroadcasts: 0, // No retries to avoid duplicates + OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + if err != nil { + return // Don't log individual failures + } + if receipt != nil && receipt.Status == 1 { + atomic.AddInt64(&confirmedCount, 1) + + // Add successfully funded delegator to EOA queue + s.addEOAToQueue(delegator.GetAddress().Hex(), fmt.Sprintf("%x", delegator.GetPrivateKey().D)) + + // No progress logging - only log when target is reached + } + }, + LogFn: func(client *txbuilder.Client, retry int, rebroadcast int, err error) { + // Only log actual send failures, not confirmation failures + if err != nil { + s.logger.Debugf("funding tx send failed: %v", err) + } + }, + }) + + if err != nil { + delegatorIndex++ + continue + } + + sentCount++ + delegatorIndex++ + + // Check if we should continue filling the block + confirmed = atomic.LoadInt64(&confirmedCount) + if confirmed >= int64(targetCount) && sentCount%maxTxsPerBlock < TransactionBatchSize { + // We have enough confirmed and we're at the end of a block cycle, stop for now + break + } + + // Small delay between transactions to ensure proper nonce ordering + // Reduce delay as we get more efficient + if sentCount < TransactionBatchSize { + time.Sleep(InitialTransactionDelay) + } else { + time.Sleep(OptimizedTransactionDelay) + } + + // Add context cancellation check + select { + case <-ctx.Done(): + return 0, ctx.Err() + default: + } + } + + // Wait for any remaining transactions to be included + time.Sleep(FundingConfirmationDelay) + + // Return the confirmed count + confirmed := atomic.LoadInt64(&confirmedCount) + return confirmed, nil +} + +// waitForFundingConfirmations waits for funding transactions to be confirmed by monitoring for new blocks +func (s *Scenario) waitForFundingConfirmations(ctx context.Context, targetConfirmations int64) error { + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + if client == nil { + return fmt.Errorf("no client available for monitoring blocks") + } + + s.logger.Infof("Waiting for funding transactions to be confirmed (expecting ~%d confirmations)...", targetConfirmations) + + // Get the starting block number + startBlock, err := client.GetEthClient().BlockNumber(ctx) + if err != nil { + return fmt.Errorf("failed to get starting block number: %w", err) + } + + // Monitor until we see at least 1 new block to ensure funding txs are included + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + + blocksWaited := uint64(0) + for { + select { + case <-ctx.Done(): + return ctx.Err() + case <-ticker.C: + // Check current block number + currentBlock, err := client.GetEthClient().BlockNumber(ctx) + if err != nil { + s.logger.Debugf("Error getting block number: %v", err) + continue + } + + // If we have new blocks + if currentBlock > startBlock { + blocksWaited = currentBlock - startBlock + s.logger.Debugf("New block %d mined (%d blocks since funding started)", currentBlock, blocksWaited) + + // Wait for at least 1 block to ensure funding transactions are included + if blocksWaited >= 1 { + s.logger.Infof("Funding transactions should be confirmed (waited %d blocks)", blocksWaited) + return nil + } + } + } + } +} + +func (s *Scenario) sendMaxBloatingTransaction(ctx context.Context, targetAuthorizations int, targetGasLimit uint64, blockCounter int) (uint64, string, int, float64, float64, string, error) { + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + if client == nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("no client available for sending max bloating transaction") + } + + // Use root wallet since we set child wallet count to 0 in max-bloating mode + wallet := s.walletPool.GetRootWallet() + + // Get suggested fees or use configured values + var feeCap *big.Int + var tipCap *big.Int + + if s.options.BaseFee > 0 { + feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(GweiPerEth)) + } + if s.options.TipFee > 0 { + tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(GweiPerEth)) + } + + if feeCap == nil || tipCap == nil { + var err error + feeCap, tipCap, err = client.GetSuggestedFee(s.walletPool.GetContext()) + if err != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to get suggested fees: %w", err) + } + } + + // Ensure minimum gas prices for inclusion + if feeCap.Cmp(big.NewInt(GweiPerEth)) < 0 { + feeCap = big.NewInt(GweiPerEth) + } + if tipCap.Cmp(big.NewInt(GweiPerEth)) < 0 { + tipCap = big.NewInt(GweiPerEth) + } + + // Use minimal amount for max bloating (focus on authorizations, not value transfer) + amount := uint256.NewInt(0) // No value transfer needed + + // Target address - use our own wallet for simplicity + toAddr := wallet.GetAddress() + + // No call data for max bloating transactions + txCallData := []byte{} + + // Build the authorizations for maximum state bloat + authorizations := s.buildMaxBloatingAuthorizations(targetAuthorizations, blockCounter) + + // Check transaction size and split into batches if needed + batches := s.splitAuthorizationsBatches(authorizations, len(txCallData)) + + if len(batches) == 1 { + // Single transaction - use existing logic + return s.sendSingleMaxBloatingTransaction(ctx, batches[0], txCallData, feeCap, tipCap, amount, toAddr, targetGasLimit, wallet, client) + } else { + // Multiple transactions needed - send them as a batch + return s.sendBatchedMaxBloatingTransactions(ctx, batches, txCallData, feeCap, tipCap, amount, toAddr, targetGasLimit, wallet, client) + } +} + +// sendSingleMaxBloatingTransaction sends a single transaction (original logic) +func (s *Scenario) sendSingleMaxBloatingTransaction(ctx context.Context, authorizations []types.SetCodeAuthorization, txCallData []byte, feeCap, tipCap *big.Int, amount *uint256.Int, toAddr common.Address, targetGasLimit uint64, wallet *txbuilder.Wallet, client *txbuilder.Client) (uint64, string, int, float64, float64, string, error) { + txData, err := txbuilder.SetCodeTx(&txbuilder.TxMetadata{ + GasFeeCap: uint256.MustFromBig(feeCap), + GasTipCap: uint256.MustFromBig(tipCap), + Gas: targetGasLimit, + To: &toAddr, + Value: amount, + Data: txCallData, + AuthList: authorizations, + }) + if err != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to build transaction metadata: %w", err) + } + + tx, err := wallet.BuildSetCodeTx(txData) + if err != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to build transaction: %w", err) + } + + // Log actual transaction size + txSize := len(tx.Data()) + if encoded, err := tx.MarshalBinary(); err == nil { + txSize = len(encoded) + } + sizeKiB := float64(txSize) / BytesPerKiB + exceedsLimit := txSize > MaxTransactionSize + limitKiB := float64(MaxTransactionSize) / BytesPerKiB + + s.logger.WithField("scenario", "eoa-delegation").Infof("MAX BLOATING TX SIZE: %d bytes (%.2f KiB) | Limit: %d bytes (%.1f KiB) | %d authorizations | Exceeds limit: %v", + txSize, sizeKiB, MaxTransactionSize, limitKiB, len(authorizations), exceedsLimit) + + // Use channels to capture transaction results + resultChan := make(chan struct { + gasUsed uint64 + blockNumber string + authCount int + gasPerAuth float64 + gasPerByte float64 + gweiTotalFee string + err error + }, 1) + + // Send the transaction + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &txbuilder.SendTransactionOptions{ + Client: client, + MaxRebroadcasts: 10, + RebroadcastInterval: 120 * time.Second, // Default rebroadcast interval + OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + if err != nil { + s.logger.WithField("rpc", client.GetName()).Errorf("max bloating tx failed: %v", err) + resultChan <- struct { + gasUsed uint64 + blockNumber string + authCount int + gasPerAuth float64 + gasPerByte float64 + gweiTotalFee string + err error + }{0, "", 0, 0, 0, "", err} + return + } + if receipt == nil { + resultChan <- struct { + gasUsed uint64 + blockNumber string + authCount int + gasPerAuth float64 + gasPerByte float64 + gweiTotalFee string + err error + }{0, "", 0, 0, 0, "", fmt.Errorf("no receipt received")} + return + } + + effectiveGasPrice := receipt.EffectiveGasPrice + if effectiveGasPrice == nil { + effectiveGasPrice = big.NewInt(0) + } + feeAmount := new(big.Int).Mul(effectiveGasPrice, big.NewInt(int64(receipt.GasUsed))) + totalAmount := new(big.Int).Add(tx.Value(), feeAmount) + wallet.SubBalance(totalAmount) + + gweiTotalFee := new(big.Int).Div(feeAmount, big.NewInt(1000000000)) + + // Calculate efficiency metrics + authCount := len(authorizations) + gasPerAuth := float64(receipt.GasUsed) / float64(authCount) + gasPerByte := gasPerAuth / EstimatedBytesPerAuth + + resultChan <- struct { + gasUsed uint64 + blockNumber string + authCount int + gasPerAuth float64 + gasPerByte float64 + gweiTotalFee string + err error + }{receipt.GasUsed, receipt.BlockNumber.String(), + authCount, + gasPerAuth, + gasPerByte, + gweiTotalFee.String(), nil} + }, + LogFn: func(client *txbuilder.Client, retry int, rebroadcast int, err error) { + logger := s.logger.WithField("rpc", client.GetName()) + if retry > 0 { + logger = logger.WithField("retry", retry) + } + if rebroadcast > 0 { + logger = logger.WithField("rebroadcast", rebroadcast) + } + if err != nil { + logger.Errorf("failed sending max bloating tx: %v", err) + } else if retry > 0 || rebroadcast > 0 { + logger.Infof("successfully sent max bloating tx") + } + }, + }) + + if err != nil { + wallet.ResetPendingNonce(ctx, client) + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to send max bloating transaction: %w", err) + } + + // Wait for transaction confirmation + result := <-resultChan + return result.gasUsed, result.blockNumber, result.authCount, result.gasPerAuth, result.gasPerByte, result.gweiTotalFee, result.err +} + +// sendBatchedMaxBloatingTransactions sends multiple transactions when size limit is exceeded +func (s *Scenario) sendBatchedMaxBloatingTransactions(ctx context.Context, batches [][]types.SetCodeAuthorization, txCallData []byte, feeCap, tipCap *big.Int, amount *uint256.Int, toAddr common.Address, targetGasLimit uint64, wallet *txbuilder.Wallet, client *txbuilder.Client) (uint64, string, int, float64, float64, string, error) { + // Aggregate results + var totalGasUsed uint64 + var totalAuthCount int + var totalFees *big.Int = big.NewInt(0) + var lastBlockNumber string + + // Create result channels for all batches upfront + resultChans := make([]chan struct { + gasUsed uint64 + blockNumber string + authCount int + gweiTotalFee string + err error + }, len(batches)) + + // Send all batches quickly with minimal delay to increase chance of same block inclusion + for batchIndex, batch := range batches { + // Create result channel for this batch + resultChans[batchIndex] = make(chan struct { + gasUsed uint64 + blockNumber string + authCount int + gweiTotalFee string + err error + }, 1) + + // Calculate appropriate gas limit for this batch based on authorization count + // Each authorization needs ~26000 gas, plus some overhead for the transaction itself + batchGasLimit := uint64(len(batch))*GasPerAuthorization + BaseTransferCost + uint64(len(txCallData)*GasPerCallDataByte) + + // Ensure we don't exceed the target limit per transaction + maxGasPerTx := targetGasLimit + if batchGasLimit > maxGasPerTx { + batchGasLimit = maxGasPerTx + } + + // Build the transaction for this batch + txData, err := txbuilder.SetCodeTx(&txbuilder.TxMetadata{ + GasFeeCap: uint256.MustFromBig(feeCap), + GasTipCap: uint256.MustFromBig(tipCap), + Gas: batchGasLimit, + To: &toAddr, + Value: amount, + Data: txCallData, + AuthList: batch, + }) + if err != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to build batch %d transaction metadata: %w", batchIndex+1, err) + } + + tx, err := wallet.BuildSetCodeTx(txData) + if err != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to build batch %d transaction: %w", batchIndex+1, err) + } + + // Send the transaction immediately without waiting for confirmation + resultChan := resultChans[batchIndex] + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &txbuilder.SendTransactionOptions{ + Client: client, + MaxRebroadcasts: MaxRebroadcasts, + RebroadcastInterval: 120 * time.Second, // Default rebroadcast interval + OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + if err != nil { + s.logger.WithField("rpc", client.GetName()).Errorf("batch %d tx failed: %v", batchIndex+1, err) + resultChan <- struct { + gasUsed uint64 + blockNumber string + authCount int + gweiTotalFee string + err error + }{0, "", 0, "", err} + return + } + if receipt == nil { + resultChan <- struct { + gasUsed uint64 + blockNumber string + authCount int + gweiTotalFee string + err error + }{0, "", 0, "", fmt.Errorf("batch %d: no receipt received", batchIndex+1)} + return + } + + effectiveGasPrice := receipt.EffectiveGasPrice + if effectiveGasPrice == nil { + effectiveGasPrice = big.NewInt(0) + } + feeAmount := new(big.Int).Mul(effectiveGasPrice, big.NewInt(int64(receipt.GasUsed))) + totalAmount := new(big.Int).Add(tx.Value(), feeAmount) + wallet.SubBalance(totalAmount) + + gweiTotalFee := new(big.Int).Div(feeAmount, big.NewInt(GweiPerEth)) + + resultChan <- struct { + gasUsed uint64 + blockNumber string + authCount int + gweiTotalFee string + err error + }{receipt.GasUsed, receipt.BlockNumber.String(), len(batch), gweiTotalFee.String(), nil} + }, + LogFn: func(client *txbuilder.Client, retry int, rebroadcast int, err error) { + logger := s.logger.WithField("rpc", client.GetName()) + if err != nil { + logger.Errorf("failed sending batch %d tx: %v", batchIndex+1, err) + } else if retry > 0 || rebroadcast > 0 { + logger.Debugf("successfully sent batch %d tx (retry/rebroadcast)", batchIndex+1) + } + }, + }) + + if err != nil { + wallet.ResetPendingNonce(ctx, client) + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to send batch %d transaction: %w", batchIndex+1, err) + } + + // No delay between batches - send as fast as possible to ensure same block inclusion + } + + // Now wait for all batch confirmations + blockNumbers := make(map[string]int) // Track which blocks contain our transactions + batchDetails := make([]string, len(batches)) // Store details of each batch + for batchIndex := range batches { + result := <-resultChans[batchIndex] + if result.err != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("batch %d failed: %w", batchIndex+1, result.err) + } + + // Aggregate successful results + totalGasUsed += result.gasUsed + totalAuthCount += result.authCount + lastBlockNumber = result.blockNumber + + // Track block numbers + blockNumbers[result.blockNumber]++ + + // Parse and add fee + if feeGwei, ok := new(big.Int).SetString(result.gweiTotalFee, 10); ok { + totalFees.Add(totalFees, feeGwei) + } + + // Store batch details + batchGasInM := float64(result.gasUsed) / GasPerMillion + gasPerAuthBatch := float64(result.gasUsed) / float64(result.authCount) + gasPerByteBatch := gasPerAuthBatch / EstimatedBytesPerAuth + + // Calculate tx size based on authorizations + txSize := s.calculateTransactionSize(len(batches[batchIndex]), len(txCallData)) + sizeKiB := float64(txSize) / BytesPerKiB + + batchDetails[batchIndex] = fmt.Sprintf("Batch %d/%d: %.2fM gas, %d auths, %.2f KiB, %.2f gas/auth, %.2f gas/byte, (block %s)", + batchIndex+1, len(batches), batchGasInM, result.authCount, sizeKiB, gasPerAuthBatch, gasPerByteBatch, result.blockNumber) + } + + // Calculate aggregate metrics + gasPerAuth := float64(totalGasUsed) / float64(totalAuthCount) + gasPerByte := gasPerAuth / EstimatedBytesPerAuth + totalGasInM := float64(totalGasUsed) / GasPerMillion + + // Build block distribution summary + var blockDistribution strings.Builder + for blockNum, txCount := range blockNumbers { + if blockDistribution.Len() > 0 { + blockDistribution.WriteString(", ") + } + blockDistribution.WriteString(fmt.Sprintf("Block #%s: %d tx", blockNum, txCount)) + } + + // Create comprehensive summary log with decorative border + s.logger.WithField("scenario", "eoa-delegation").Infof(`════════════════ BATCHED MAX BLOATING SUMMARY ════════════════ +Individual Batches: +%s + +Block Distribution: %s + +Aggregate Metrics: +- Total Gas Used: %.2fM +- Total Authorizations: %d +- Gas per Auth: %.2f +- Gas per Byte: %.2f`, + strings.Join(batchDetails, "\n"), + blockDistribution.String(), + totalGasInM, + totalAuthCount, + gasPerAuth, + gasPerByte) + + return totalGasUsed, lastBlockNumber, totalAuthCount, gasPerAuth, gasPerByte, totalFees.String(), nil +} + +// eoaWorker runs in a separate goroutine and writes funded EOAs to EOAs.json +// when the semaphore is open (green). It sleeps when the semaphore is closed (red). +func (s *Scenario) eoaWorker() { + defer s.workerWg.Done() + + for { + select { + case <-s.workerDone: + // Shutdown signal received + return + case <-s.workerSemaphore: + // Semaphore is green, process the queue + s.processEOAQueue() + } + } +} + +// processEOAQueue drains the EOA queue and writes entries to EOAs.json +func (s *Scenario) processEOAQueue() { + for { + // Check if there are items in the queue + s.eoaQueueMutex.Lock() + if len(s.eoaQueue) == 0 { + s.eoaQueueMutex.Unlock() + return // Queue is empty, exit processing + } + + // Dequeue all items (FIFO) + eoasToWrite := make([]EOAEntry, len(s.eoaQueue)) + copy(eoasToWrite, s.eoaQueue) + s.eoaQueue = s.eoaQueue[:0] // Clear the queue + s.eoaQueueMutex.Unlock() + + // Write to file + err := s.writeEOAsToFile(eoasToWrite) + if err != nil { + s.logger.Errorf("failed to write EOAs to file: %v", err) + // Re-queue the items if write failed + s.eoaQueueMutex.Lock() + s.eoaQueue = append(eoasToWrite, s.eoaQueue...) + s.eoaQueueMutex.Unlock() + return + } + + } +} + +// writeEOAsToFile appends EOA entries to EOAs.json file +func (s *Scenario) writeEOAsToFile(eoas []EOAEntry) error { + if len(eoas) == 0 { + return nil + } + + fileName := "EOAs.json" + + // Read existing entries if file exists + var existingEntries []EOAEntry + if data, err := os.ReadFile(fileName); err == nil { + json.Unmarshal(data, &existingEntries) + } + + // Append new entries + allEntries := append(existingEntries, eoas...) + + // Write back to file + data, err := json.MarshalIndent(allEntries, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal EOA entries: %w", err) + } + + err = os.WriteFile(fileName, data, 0644) + if err != nil { + return fmt.Errorf("failed to write EOAs.json: %w", err) + } + + return nil +} + +// addEOAToQueue adds a funded EOA to the queue +func (s *Scenario) addEOAToQueue(address, privateKey string) { + s.eoaQueueMutex.Lock() + defer s.eoaQueueMutex.Unlock() + + entry := EOAEntry{ + Address: address, + PrivateKey: privateKey, + } + + s.eoaQueue = append(s.eoaQueue, entry) +} + +// openWorkerSemaphore opens the semaphore (green light) allowing the worker to process +func (s *Scenario) openWorkerSemaphore() { + select { + case s.workerSemaphore <- struct{}{}: + // Semaphore opened successfully + default: + // Semaphore already open, do nothing + } +} + +// closeWorkerSemaphore closes the semaphore (red light) putting the worker to sleep +func (s *Scenario) closeWorkerSemaphore() { + select { + case <-s.workerSemaphore: + // Semaphore closed successfully + default: + // Semaphore already closed, do nothing + } +} + +// shutdownWorker signals the worker to stop and waits for it to finish +func (s *Scenario) shutdownWorker() { + close(s.workerDone) + s.workerWg.Wait() +} + +// calculateTransactionSize estimates the serialized size of a transaction with given authorizations +func (s *Scenario) calculateTransactionSize(authCount int, callDataSize int) int { + // Estimation based on empirical data and RLP encoding structure: + // - Base transaction overhead: ~200 bytes + // - Each SetCodeAuthorization: ~94 bytes (based on actual observed data) + // - Call data: variable size + // - Additional RLP encoding overhead: ~50 bytes + + baseSize := TransactionBaseOverhead + callDataSize + TransactionExtraOverhead + authSize := authCount * ActualBytesPerAuth + return baseSize + authSize +} + +// splitAuthorizationsBatches splits authorizations into batches that fit within transaction size limit +func (s *Scenario) splitAuthorizationsBatches(authorizations []types.SetCodeAuthorization, callDataSize int) [][]types.SetCodeAuthorization { + if len(authorizations) == 0 { + return [][]types.SetCodeAuthorization{authorizations} + } + + // To get closer to 128KiB limit, we need to adjust our estimate + // Using a safety factor of 0.95 to stay just under the limit + targetSize := MaxTransactionSize * TransactionSizeSafetyFactor / 100 // Safety margin + + maxAuthsPerTx := (targetSize - TransactionBaseOverhead - callDataSize) / ActualBytesPerAuth + if maxAuthsPerTx <= 0 { + s.logger.Warnf("Transaction call data too large, using minimal batch size of 1") + maxAuthsPerTx = 1 + } + + // If all authorizations fit in one transaction, return as single batch + if len(authorizations) <= maxAuthsPerTx { + estimatedSize := s.calculateTransactionSize(len(authorizations), callDataSize) + s.logger.Infof("All %d authorizations fit in single transaction (estimated size: %d bytes)", len(authorizations), estimatedSize) + return [][]types.SetCodeAuthorization{authorizations} + } + + // Split into multiple batches + var batches [][]types.SetCodeAuthorization + for i := 0; i < len(authorizations); i += maxAuthsPerTx { + end := i + maxAuthsPerTx + if end > len(authorizations) { + end = len(authorizations) + } + batch := authorizations[i:end] + batches = append(batches, batch) + } + + s.logger.Infof("Split %d authorizations into %d batches (max %d auths per batch, target size: %.2f KiB)", + len(authorizations), len(batches), maxAuthsPerTx, float64(targetSize)/BytesPerKiB) + return batches +} From e36c0c26cb5b31f4e6353903a7fa49f786cd6632 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Fri, 13 Jun 2025 18:34:11 +0200 Subject: [PATCH 24/39] feat(rand_sstore_bloater): add SSTOREStorageBloater contract and scenario for state bloat testing The idea is that it performs the maximum amount of SSTORE possible with the available gas limit within a single tx execution that consumes it all. --- scenarios/scenarios.go | 11 + .../statebloat/rand_sstore_bloater/README.md | 124 +++++ .../contract/SSTOREStorageBloater.go | 225 +++++++++ .../contract/SSTOREStorageBloater.sol | 45 ++ .../rand_sstore_bloater.go | 441 ++++++++++++++++++ 5 files changed, 846 insertions(+) create mode 100644 scenarios/statebloat/rand_sstore_bloater/README.md create mode 100644 scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.go create mode 100644 scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.sol create mode 100644 scenarios/statebloat/rand_sstore_bloater/rand_sstore_bloater.go diff --git a/scenarios/scenarios.go b/scenarios/scenarios.go index e0f32a82..b4e388ee 100644 --- a/scenarios/scenarios.go +++ b/scenarios/scenarios.go @@ -13,6 +13,12 @@ import ( "github.com/ethpandaops/spamoor/scenarios/erctx" "github.com/ethpandaops/spamoor/scenarios/gasburnertx" "github.com/ethpandaops/spamoor/scenarios/setcodetx" + contractdeploy "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy" + eoadelegation "github.com/ethpandaops/spamoor/scenarios/statebloat/eoa_delegation" + + //erc20maxtransfers "github.com/ethpandaops/spamoor/scenarios/statebloat/erc20_max_transfers" + //extcodesizeoverload "github.com/ethpandaops/spamoor/scenarios/statebloat/extcodesize-overload" + randsstorebloater "github.com/ethpandaops/spamoor/scenarios/statebloat/rand_sstore_bloater" uniswapswaps "github.com/ethpandaops/spamoor/scenarios/uniswap-swaps" "github.com/ethpandaops/spamoor/scenarios/wallets" ) @@ -28,8 +34,13 @@ var ScenarioDescriptors = []*scenariotypes.ScenarioDescriptor{ &erctx.ScenarioDescriptor, &gasburnertx.ScenarioDescriptor, &setcodetx.ScenarioDescriptor, + &randsstorebloater.ScenarioDescriptor, &uniswapswaps.ScenarioDescriptor, &wallets.ScenarioDescriptor, + &contractdeploy.ScenarioDescriptor, + &eoadelegation.ScenarioDescriptor, + //&erc20maxtransfers.ScenarioDescriptor, + //&extcodesizeoverload.ScenarioDescriptor, } func GetScenario(name string) *scenariotypes.ScenarioDescriptor { diff --git a/scenarios/statebloat/rand_sstore_bloater/README.md b/scenarios/statebloat/rand_sstore_bloater/README.md new file mode 100644 index 00000000..f7a9c6b6 --- /dev/null +++ b/scenarios/statebloat/rand_sstore_bloater/README.md @@ -0,0 +1,124 @@ +# 🔥 Random SSTORE State Bloater + +This scenario maximizes state growth by performing the maximum number of SSTORE operations per block using random key distribution. + +## 🛠️ Contract Compilation + +### Prerequisites +- Solidity compiler (solc) version 0.8.30 or compatible +- Go 1.16+ (for go:embed directive) + +### Compiling the Contract + +To compile the SSTOREStorageBloater contract: + +```bash +cd scenarios/statebloat/rand_sstore_bloater/contract +solc --optimize --optimize-runs 200 --combined-json abi,bin SSTOREStorageBloater.sol +``` + +### Extracting ABI and Bytecode + +The compilation output is in JSON format. Extract the ABI and bytecode: + +```bash +# Extract ABI (already done) +jq -r '.contracts["SSTOREStorageBloater.sol:SSTOREStorageBloater"].abi' < output.json > SSTOREStorageBloater.abi + +# Extract bytecode (already done) +jq -r '.contracts["SSTOREStorageBloater.sol:SSTOREStorageBloater"].bin' < output.json > SSTOREStorageBloater.bin +``` + +### Regenerating Go Bindings (Optional) + +If you need to regenerate the Go bindings: + +```bash +abigen --abi SSTOREStorageBloater.abi --bin SSTOREStorageBloater.bin --pkg contract --out SSTOREStorageBloater.go +``` + +**Note**: The Go scenario code uses `go:embed` directives to automatically include the ABI and bytecode files at compile time. + +## How it Works + +1. **Contract Deployment**: Deploys an optimized `SSTOREStorageBloater` contract that uses assembly for minimal overhead +2. **Two-Stage Process**: + - **Stage 1**: Creates new storage slots (0 → non-zero transitions) + - **Stage 2**: Updates existing storage slots (non-zero → non-zero transitions) +3. **Key Distribution**: Uses curve25519 prime multiplication to distribute keys across the entire storage space, maximizing trie node creation +4. **Adaptive Gas Estimation**: Dynamically adjusts gas estimates based on actual usage to maximize slots per transaction + +## ⛽ Gas Cost Breakdown + +### Actual Gas Costs (Measured) +The actual gas cost per SSTORE operation is higher than the base opcode cost due to additional overhead: + +**For New Slots (0 → non-zero):** +- Base SSTORE cost: 20,000 gas +- Assembly loop overhead per iteration: + - MULMOD for key calculation: ~8 gas + - TIMESTAMP calls: ~2 gas + - AND operation: ~3 gas + - Loop control (JUMPI, LT, ADD): ~10 gas +- **Total: ~22,000 gas per slot** + +**For Updates (non-zero → non-zero):** +- Base SSTORE cost: 5,000 gas +- Same assembly overhead: ~2,000 gas +- **Total: ~7,000 gas per slot** + +**Transaction Overhead:** +- Base transaction cost: 21,000 gas +- Function selector matching: ~100 gas +- ABI decoding (uint256 parameter): ~1,000 gas +- Contract code loading: ~2,600 gas +- Memory allocation: ~1,000 gas +- Function dispatch: ~300 gas +- Return handling: ~1,000 gas +- Safety margin: ~73,000 gas +- **Total: ~100,000 gas overhead** + +Example with 30M gas limit block (97% utilization): +- Stage 1: ~1,300 new slots per block +- Stage 2: ~4,100 slot updates per block + +## 🚀 Usage + +### Build +```bash +go build -o bin/spamoor cmd/spamoor/main.go +``` + +### Run +```bash +./bin/spamoor --privkey --rpchost http://localhost:8545 rand_sstore_bloater [flags] +``` + +#### Flags +- `--basefee` - Base fee per gas in gwei (default: 10) +- `--tipfee` - Tip fee per gas in gwei (default: 2) + +### Example +```bash +./bin/spamoor --privkey ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + --rpchost http://localhost:8545 rand_sstore_bloater +``` + +## 📊 Deployment Tracking + +The scenario tracks all contract deployments and storage operations in `deployments_sstore_bloating.json`. This file enables future scenarios to perform targeted SLOAD operations on known storage slots. + +### File Format +```json +{ + "0xContractAddress": { + "storage_rounds": [ + { + "block_number": 123, + "timestamp": 1234567890 + }, + ... + ] + } +} +``` \ No newline at end of file diff --git a/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.go b/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.go new file mode 100644 index 00000000..b99fb9f5 --- /dev/null +++ b/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.go @@ -0,0 +1,225 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contract + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ContractMetaData contains all meta data concerning the Contract contract. +var ContractMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"createSlots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080604052348015600e575f5ffd5b5060b780601a5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c8063e3b393a414602a575b5f5ffd5b60396035366004606b565b603b565b005b6013600160ff1b0381600143034042185f5b828110156064575f1984838301098055600101604d565b5050505050565b5f60208284031215607a575f5ffd5b503591905056fea26469706673582212204ef28faab84898d88945da94b05dca578974093de11f6a0be4b796396638d88264736f6c634300081e0033", +} + +// ContractABI is the input ABI used to generate the binding from. +// Deprecated: Use ContractMetaData.ABI instead. +var ContractABI = ContractMetaData.ABI + +// ContractBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ContractMetaData.Bin instead. +var ContractBin = ContractMetaData.Bin + +// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. +func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Contract, error) { + parsed, err := ContractMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil +} + +// Contract is an auto generated Go binding around an Ethereum contract. +type Contract struct { + ContractCaller // Read-only binding to the contract + ContractTransactor // Write-only binding to the contract + ContractFilterer // Log filterer for contract events +} + +// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. +type ContractCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ContractTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ContractFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ContractSession struct { + Contract *Contract // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ContractCallerSession struct { + Contract *ContractCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ContractTransactorSession struct { + Contract *ContractTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. +type ContractRaw struct { + Contract *Contract // Generic contract binding to access the raw methods on +} + +// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ContractCallerRaw struct { + Contract *ContractCaller // Generic read-only contract binding to access the raw methods on +} + +// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ContractTransactorRaw struct { + Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewContract creates a new instance of Contract, bound to a specific deployed contract. +func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { + contract, err := bindContract(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil +} + +// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. +func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { + contract, err := bindContract(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ContractCaller{contract: contract}, nil +} + +// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. +func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { + contract, err := bindContract(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ContractTransactor{contract: contract}, nil +} + +// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. +func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { + contract, err := bindContract(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ContractFilterer{contract: contract}, nil +} + +// bindContract binds a generic wrapper to an already deployed contract. +func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ContractMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Contract.Contract.ContractTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Contract.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Contract.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Contract.Contract.contract.Transact(opts, method, params...) +} + +// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. +// +// Solidity: function createSlots(uint256 count) returns() +func (_Contract *ContractTransactor) CreateSlots(opts *bind.TransactOpts, count *big.Int) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "createSlots", count) +} + +// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. +// +// Solidity: function createSlots(uint256 count) returns() +func (_Contract *ContractSession) CreateSlots(count *big.Int) (*types.Transaction, error) { + return _Contract.Contract.CreateSlots(&_Contract.TransactOpts, count) +} + +// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. +// +// Solidity: function createSlots(uint256 count) returns() +func (_Contract *ContractTransactorSession) CreateSlots(count *big.Int) (*types.Transaction, error) { + return _Contract.Contract.CreateSlots(&_Contract.TransactOpts, count) +} + diff --git a/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.sol b/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.sol new file mode 100644 index 00000000..6a48bf81 --- /dev/null +++ b/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @title SSTOREStorageBloater + * @dev Optimized contract for maximum SSTORE operations using curve25519 prime (2^255 - 19) + * Uses assembly for gas efficiency and distributes keys across storage space + */ +contract SSTOREStorageBloater { + // Counter to track total slots created (stored at slot 0) + uint256 private counter; + + // curve25519 prime: 2^255 - 19 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed + uint256 private constant CURVE25519_PRIME = + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed; + + /** + * @dev Creates new storage slots (0 -> non-zero transition, ~20k gas each) + * @param count Number of slots to create + */ + function createSlots(uint256 count) external { + assembly { + // Load current counter from storage slot 0 + let prime := CURVE25519_PRIME + let endCounter := count + + // Calculate pseudo-random offset using block data + // XOR timestamp with previous block hash for randomness + let offset := xor(timestamp(), blockhash(sub(number(), 1))) + + // Create slots with distributed keys + for { + let i := 0 + } lt(i, endCounter) { + i := add(i, 1) + } { + // Calculate key = (offset + i) * CURVE25519_PRIME + let key := mulmod(add(offset, i), prime, not(0)) + + // Store value = key + sstore(key, key) + } + } + } +} diff --git a/scenarios/statebloat/rand_sstore_bloater/rand_sstore_bloater.go b/scenarios/statebloat/rand_sstore_bloater/rand_sstore_bloater.go new file mode 100644 index 00000000..e7708ccc --- /dev/null +++ b/scenarios/statebloat/rand_sstore_bloater/rand_sstore_bloater.go @@ -0,0 +1,441 @@ +package randsstorebloater + +import ( + "context" + _ "embed" + "encoding/json" + "fmt" + "math/big" + "os" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/sirupsen/logrus" + "github.com/spf13/pflag" + "gopkg.in/yaml.v3" + + "github.com/ethpandaops/spamoor/scenarios/statebloat/rand_sstore_bloater/contract" + "github.com/ethpandaops/spamoor/scenariotypes" + "github.com/ethpandaops/spamoor/spamoor" +) + +//go:embed contract/SSTOREStorageBloater.abi +var contractABIBytes []byte + +//go:embed contract/SSTOREStorageBloater.bin +var contractBytecodeHex []byte + +// Constants for SSTORE operations +const ( + // Base Ethereum transaction cost + BaseTxCost = uint64(21000) + + // Function call overhead (measured from actual transactions) + // Includes: function selector, ABI decoding, contract loading, etc. + FunctionCallOverhead = uint64(1556) + + // Gas cost per iteration (measured from actual transactions) + // Includes: SSTORE (0→non-zero), MULMOD, loop overhead, stack operations + // Measured: 22,165 gas per iteration + GasPerNewSlotIteration = uint64(22165) + + // Contract deployment and call overhead + EstimatedDeployGas = uint64(500000) // Deployment gas for our contract + + // Safety margins and multipliers + GasLimitSafetyMargin = 0.99 // Use 99% of block gas limit (1% margin for gas price variations) + + // Deployment tracking file + DeploymentFileName = "deployments_sstore_bloating.json" +) + +// BlockInfo stores block information for each storage round +type BlockInfo struct { + BlockNumber uint64 `json:"block_number"` + Timestamp uint64 `json:"timestamp"` +} + +// DeploymentData tracks a single contract deployment and its storage rounds +type DeploymentData struct { + StorageRounds []BlockInfo `json:"storage_rounds"` +} + +// DeploymentFile represents the entire deployment tracking file +type DeploymentFile map[string]*DeploymentData // key is contract address + +type ScenarioOptions struct { + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` +} + +type Scenario struct { + options ScenarioOptions + logger *logrus.Entry + walletPool *spamoor.WalletPool + + // Contract state + contractAddress common.Address + contractABI abi.ABI + contractInstance *contract.Contract // Generated contract binding + isDeployed bool + deployMutex sync.Mutex + + // Scenario state + totalSlots uint64 // Total number of slots created + cycleCount uint64 // Number of complete create/update cycles + roundNumber uint64 // Current round number for SSTORE bloating + + // Adaptive gas tracking + actualGasPerNewSlotIteration uint64 // Dynamically adjusted based on actual usage + successfulSlotCounts map[uint64]bool // Track successful slot counts to avoid retries + + // Cached values + chainID *big.Int + chainIDOnce sync.Once + chainIDError error +} + +var ScenarioName = "rand_sstore_bloater" +var ScenarioDefaultOptions = ScenarioOptions{ + BaseFee: 10, // 10 gwei default + TipFee: 2, // 2 gwei default +} +var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ + Name: ScenarioName, + Description: "Maximum state bloat via SSTORE operations using curve25519 prime dispersion", + DefaultOptions: ScenarioDefaultOptions, + NewScenario: newScenario, +} + +func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { + return &Scenario{ + logger: logger.WithField("scenario", ScenarioName), + actualGasPerNewSlotIteration: GasPerNewSlotIteration, // Start with estimated values + successfulSlotCounts: make(map[uint64]bool), + } +} + +func (s *Scenario) Flags(flags *pflag.FlagSet) error { + flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Base fee per gas in gwei") + flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Tip fee per gas in gwei") + return nil +} + +func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { + s.walletPool = walletPool + + if config != "" { + err := yaml.Unmarshal([]byte(config), &s.options) + if err != nil { + return fmt.Errorf("failed to unmarshal config: %w", err) + } + } + + // Use only root wallet for simplicity + s.walletPool.SetWalletCount(1) + + // Parse contract ABI + parsedABI, err := abi.JSON(strings.NewReader(string(contractABIBytes))) + if err != nil { + return fmt.Errorf("failed to parse contract ABI: %w", err) + } + s.contractABI = parsedABI + + return nil +} + +func (s *Scenario) Config() string { + yamlBytes, _ := yaml.Marshal(&s.options) + return string(yamlBytes) +} + +// loadDeploymentFile loads the deployment tracking file or creates an empty one +func loadDeploymentFile() (DeploymentFile, error) { + data, err := os.ReadFile(DeploymentFileName) + if err != nil { + if os.IsNotExist(err) { + // File doesn't exist, return empty map + return make(DeploymentFile), nil + } + return nil, fmt.Errorf("failed to read deployment file: %w", err) + } + + var deployments DeploymentFile + if err := json.Unmarshal(data, &deployments); err != nil { + return nil, fmt.Errorf("failed to unmarshal deployment file: %w", err) + } + + return deployments, nil +} + +// saveDeploymentFile saves the deployment tracking file +func saveDeploymentFile(deployments DeploymentFile) error { + data, err := json.MarshalIndent(deployments, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal deployment file: %w", err) + } + + if err := os.WriteFile(DeploymentFileName, data, 0644); err != nil { + return fmt.Errorf("failed to write deployment file: %w", err) + } + + return nil +} + +func (s *Scenario) getChainID(ctx context.Context) (*big.Int, error) { + s.chainIDOnce.Do(func() { + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + if client == nil { + s.chainIDError = fmt.Errorf("no client available for chain ID") + return + } + s.chainID, s.chainIDError = client.GetChainId(ctx) + }) + return s.chainID, s.chainIDError +} + +func (s *Scenario) deployContract(ctx context.Context) error { + s.deployMutex.Lock() + defer s.deployMutex.Unlock() + + if s.isDeployed { + return nil + } + + s.logger.Info("Deploying SSTOREStorageBloater contract...") + + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + if client == nil { + return fmt.Errorf("no client available") + } + + wallet := s.walletPool.GetRootWallet() + if wallet == nil { + return fmt.Errorf("no wallet available") + } + + chainID, err := s.getChainID(ctx) + if err != nil { + return err + } + + auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), chainID) + if err != nil { + return fmt.Errorf("failed to create transactor: %w", err) + } + + // Set gas parameters + auth.GasLimit = EstimatedDeployGas + auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) + auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) + + // Deploy contract using generated bindings + address, tx, contractInstance, err := contract.DeployContract(auth, client.GetEthClient()) + if err != nil { + return fmt.Errorf("failed to deploy contract: %w", err) + } + + s.logger.WithField("tx", tx.Hash().Hex()).Info("Contract deployment transaction sent") + + // Wait for deployment + receipt, err := bind.WaitMined(ctx, client.GetEthClient(), tx) + if err != nil { + return fmt.Errorf("failed to wait for deployment: %w", err) + } + + if receipt.Status != 1 { + return fmt.Errorf("contract deployment failed") + } + + s.contractAddress = address + s.contractInstance = contractInstance + s.isDeployed = true + + // No need to reset nonce - the wallet manager handles it automatically + + // Track deployment in JSON file + deployments, err := loadDeploymentFile() + if err != nil { + s.logger.Warnf("failed to load deployment file: %v", err) + deployments = make(DeploymentFile) + } + + // Initialize deployment data for this contract + deployments[address.Hex()] = &DeploymentData{ + StorageRounds: []BlockInfo{}, + } + + if err := saveDeploymentFile(deployments); err != nil { + s.logger.Warnf("failed to save deployment file: %v", err) + } + + s.logger.WithField("address", address.Hex()).Info("SSTOREStorageBloater contract deployed successfully") + + return nil +} + +func (s *Scenario) Run(ctx context.Context) error { + s.logger.Infof("starting scenario: %s", ScenarioName) + defer s.logger.Infof("scenario %s finished.", ScenarioName) + + // Deploy the contract if not already deployed + if !s.isDeployed { + if err := s.deployContract(ctx); err != nil { + return fmt.Errorf("failed to deploy contract: %w", err) + } + } + + // Get network parameters + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + if client == nil { + return fmt.Errorf("no client available") + } + + // Main loop - alternate between creating and updating slots + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + // Get current block gas limit + latestBlock, err := client.GetEthClient().BlockByNumber(ctx, nil) + if err != nil { + s.logger.Warnf("failed to get latest block: %v", err) + time.Sleep(5 * time.Second) + continue + } + + blockGasLimit := latestBlock.GasLimit() + targetGas := uint64(float64(blockGasLimit) * GasLimitSafetyMargin) + + // Never stop spamming SSTORE operations. + s.roundNumber++ + if err := s.executeCreateSlots(ctx, targetGas, blockGasLimit); err != nil { + s.logger.Errorf("failed to create slots: %v", err) + time.Sleep(5 * time.Second) + continue + } + } +} + +func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blockGasLimit uint64) error { + // Calculate how many slots we can create with precise gas costs + // Account for base tx cost and function overhead + availableGas := targetGas - BaseTxCost - FunctionCallOverhead + slotsToCreate := availableGas / s.actualGasPerNewSlotIteration // Integer division rounds down + + if slotsToCreate == 0 { + return fmt.Errorf("not enough gas to create any slots") + } + + // Get client and wallet + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + if client == nil { + return fmt.Errorf("no client available") + } + + wallet := s.walletPool.GetRootWallet() + if wallet == nil { + return fmt.Errorf("no wallet available") + } + + // Create transaction options + chainID, err := s.getChainID(ctx) + if err != nil { + return err + } + + auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), chainID) + if err != nil { + return fmt.Errorf("failed to create transactor: %w", err) + } + + // Set gas parameters + auth.GasLimit = targetGas + auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) + auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) + + // Execute transaction using contract bindings + tx, err := s.contractInstance.CreateSlots(auth, big.NewInt(int64(slotsToCreate))) + if err != nil { + // Check if it's an out-of-gas error + if strings.Contains(err.Error(), "out of gas") || strings.Contains(err.Error(), "OutOfGas") { + // Increase our gas estimate by 10% + s.actualGasPerNewSlotIteration = uint64(float64(s.actualGasPerNewSlotIteration) * 1.1) + s.logger.Warnf("Out of gas error detected. Adjusting gas per slot estimate to %d", s.actualGasPerNewSlotIteration) + } + return err + } + + // Wait for transaction confirmation + receipt, err := bind.WaitMined(ctx, client.GetEthClient(), tx) + if err != nil { + return fmt.Errorf("failed to wait for transaction: %w", err) + } + + if receipt.Status != 1 { + return fmt.Errorf("transaction failed") + } + + // Mark this slot count as successful + s.successfulSlotCounts[slotsToCreate] = true + + // Update metrics and adaptive gas tracking + s.totalSlots += slotsToCreate + totalOverhead := BaseTxCost + FunctionCallOverhead + actualGasPerSlotIteration := (receipt.GasUsed - totalOverhead) / slotsToCreate + + // Update our gas estimate using exponential moving average + // New estimate = 0.7 * old estimate + 0.3 * actual + s.actualGasPerNewSlotIteration = uint64(float64(s.actualGasPerNewSlotIteration)*0.7 + float64(actualGasPerSlotIteration)*0.3) + + // Get previous block info for tracking + prevBlockNumber := receipt.BlockNumber.Uint64() - 1 + prevBlock, err := client.GetEthClient().BlockByNumber(ctx, big.NewInt(int64(prevBlockNumber))) + if err != nil { + s.logger.Warnf("failed to get previous block info: %v", err) + } else { + // Track this storage round in deployment file + deployments, err := loadDeploymentFile() + if err != nil { + s.logger.Warnf("failed to load deployment file: %v", err) + } else if deployments != nil { + contractAddr := s.contractAddress.Hex() + if deploymentData, exists := deployments[contractAddr]; exists { + // Append new block info + deploymentData.StorageRounds = append(deploymentData.StorageRounds, BlockInfo{ + BlockNumber: prevBlockNumber, + Timestamp: prevBlock.Time(), + }) + + if err := saveDeploymentFile(deployments); err != nil { + s.logger.Warnf("failed to save deployment file: %v", err) + } + } + } + } + + // Calculate MB written in this transaction (64 bytes per slot: 32 byte key + 32 byte value) + mbWrittenThisTx := float64(slotsToCreate*64) / (1024 * 1024) + + // Calculate block utilization percentage + blockUtilization := float64(receipt.GasUsed) / float64(blockGasLimit) * 100 + + s.logger.WithFields(logrus.Fields{ + "block_number": receipt.BlockNumber, + "gas_used": receipt.GasUsed, + "slots_created": slotsToCreate, + "gas_per_slot": actualGasPerSlotIteration, + "total_slots": s.totalSlots, + "mb_written": mbWrittenThisTx, + "block_utilization": fmt.Sprintf("%.2f%%", blockUtilization), + }).Info("SSTORE bloating round summary") + + return nil +} From 94117b43d72c86922880d030268a80b6b8673ae9 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 18 Jun 2025 11:10:32 +0200 Subject: [PATCH 25/39] feat(erc20_max_transfers): add ERC20 Max Transfers scenario and implementation The scenario uses deployed StateBloatToken contracts from `deployments.json` to send the maximum possible number of ERC20 transfers per block. Each transfer sends 1 token to a unique, never-before-used address, maximizing state growth. --- scenarios/scenarios.go | 10 + .../statebloat/erc20_max_transfers/README.md | 96 ++ .../erc20_max_transfers.go | 829 ++++++++++++++++++ 3 files changed, 935 insertions(+) create mode 100644 scenarios/statebloat/erc20_max_transfers/README.md create mode 100644 scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go diff --git a/scenarios/scenarios.go b/scenarios/scenarios.go index e0f32a82..1a7b935a 100644 --- a/scenarios/scenarios.go +++ b/scenarios/scenarios.go @@ -13,6 +13,12 @@ import ( "github.com/ethpandaops/spamoor/scenarios/erctx" "github.com/ethpandaops/spamoor/scenarios/gasburnertx" "github.com/ethpandaops/spamoor/scenarios/setcodetx" + contractdeploy "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy" + eoadelegation "github.com/ethpandaops/spamoor/scenarios/statebloat/eoa_delegation" + erc20maxtransfers "github.com/ethpandaops/spamoor/scenarios/statebloat/erc20_max_transfers" + + //extcodesizeoverload "github.com/ethpandaops/spamoor/scenarios/statebloat/extcodesize-overload" + uniswapswaps "github.com/ethpandaops/spamoor/scenarios/uniswap-swaps" "github.com/ethpandaops/spamoor/scenarios/wallets" ) @@ -30,6 +36,10 @@ var ScenarioDescriptors = []*scenariotypes.ScenarioDescriptor{ &setcodetx.ScenarioDescriptor, &uniswapswaps.ScenarioDescriptor, &wallets.ScenarioDescriptor, + &contractdeploy.ScenarioDescriptor, + &eoadelegation.ScenarioDescriptor, + &erc20maxtransfers.ScenarioDescriptor, + //&extcodesizeoverload.ScenarioDescriptor, } func GetScenario(name string) *scenariotypes.ScenarioDescriptor { diff --git a/scenarios/statebloat/erc20_max_transfers/README.md b/scenarios/statebloat/erc20_max_transfers/README.md new file mode 100644 index 00000000..f1f349b1 --- /dev/null +++ b/scenarios/statebloat/erc20_max_transfers/README.md @@ -0,0 +1,96 @@ +# ERC20 Max Transfers Scenario + +This scenario maximizes the number of ERC20 token transfers per block to unique recipient addresses, creating state bloat through new account storage entries. + +## Overview + +The scenario uses deployed StateBloatToken contracts from `deployments.json` to send the maximum possible number of ERC20 transfers per block. Each transfer sends 1 token to a unique, never-before-used address, maximizing state growth. + +## Features + +- **Dynamic Block Gas Limit**: Fetches the actual network block gas limit before starting +- **Self-Adjusting Transfer Count**: Automatically adjusts the number of transfers based on actual gas usage +- **Unique Recipients**: Generates deterministic unique addresses for each transfer +- **Minimum Gas Fees**: Uses configured minimum gas fees (default: 10 gwei base, 5 gwei tip) +- **Round-Robin Contract Usage**: Distributes transfers across multiple deployed contracts +- **Recipient Tracking**: Saves all recipient addresses to `recipients.json` for analysis + +## Configuration + +### Command Line Flags + +- `--basefee`: Max fee per gas in gwei (default: 10) +- `--tipfee`: Max tip per gas in gwei (default: 5) +- `--contract`: Specific contract address to use (default: rotate through all) + +### YAML Configuration + +```yaml +basefee: 10 +tipfee: 5 +contract: "" # Empty string means use all contracts +``` + +## How It Works + +1. **Initialization**: + - Loads deployed contracts and private key from `deployments.json` + - Sets up the deployer wallet (which holds all tokens) + - Fetches network block gas limit + +2. **Transfer Phase**: + - Calculates optimal transfer count based on gas limit + - Generates unique recipient addresses deterministically + - Sends transfers in batches with minimal delays + - Uses round-robin contract selection + +3. **Analysis Phase**: + - Tracks confirmed transfers and gas usage + - Calculates actual gas per transfer + - Adjusts transfer count for next iteration + - Saves recipient data to file + +4. **Self-Adjustment**: + - If under target gas usage: increases transfers + - If over target gas usage: decreases transfers + - Aims for 99.5% block utilization + +## State Growth Impact + +Each successful transfer creates: +- New account entry for the recipient (~100 bytes) +- Token balance storage slot for the recipient +- Estimated state growth: 100 bytes per transfer + +## Output + +The scenario logs detailed metrics for each block: +- Number of transfers sent and confirmed +- Unique recipients created +- Gas usage and block utilization +- Estimated state growth +- Cumulative totals + +Recipient addresses are saved to `recipients.json` with: +- Address +- Block number +- Tokens sent + +## Requirements + +- Deployed StateBloatToken contracts (via contract_deploy scenario) +- Deployer private key with full token supply +- Sufficient ETH for gas fees + +## Example Usage + +```bash +# Use default settings +./spamoor scenario --scenario erc20-max-transfers + +# Custom gas fees +./spamoor scenario --scenario erc20-max-transfers --basefee 20 --tipfee 10 + +# Use specific contract only +./spamoor scenario --scenario erc20-max-transfers --contract 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 +``` diff --git a/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go b/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go new file mode 100644 index 00000000..51c000d0 --- /dev/null +++ b/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go @@ -0,0 +1,829 @@ +package erc20maxtransfers + +import ( + "context" + "crypto/rand" + "crypto/sha256" + "encoding/binary" + "encoding/json" + "fmt" + "math/big" + "os" + "strings" + "sync" + "sync/atomic" + "time" + + "gopkg.in/yaml.v3" + + "github.com/ethereum/go-ethereum/accounts/abi" + //"github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/holiman/uint256" + "github.com/sirupsen/logrus" + "github.com/spf13/pflag" + + contract "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy/contract" + "github.com/ethpandaops/spamoor/scenariotypes" + "github.com/ethpandaops/spamoor/spamoor" + "github.com/ethpandaops/spamoor/txbuilder" +) + +// Constants for ERC20 transfer operations +const ( + // ERC20TransferGasCost - gas cost for a standard ERC20 transfer (updated to 70K) + ERC20TransferGasCost = 70000 + // DefaultBaseFeeGwei - default base fee in gwei + DefaultBaseFeeGwei = 10 + // DefaultTipFeeGwei - default tip fee in gwei + DefaultTipFeeGwei = 5 + // TokenTransferAmount - amount of tokens to transfer (1 token in smallest unit) + TokenTransferAmount = 1 + // DefaultTargetGasRatio - target percentage of block gas limit to use (99.5% for minimal safety margin) + DefaultTargetGasRatio = 0.995 + // FallbackBlockGasLimit - fallback gas limit if network query fails + FallbackBlockGasLimit = 30000000 + // GweiPerEth - conversion factor from Gwei to Wei + GweiPerEth = 1000000000 + // BlockMiningTimeout - timeout for waiting for a new block to be mined + BlockMiningTimeout = 30 * time.Second + // BlockPollingInterval - interval for checking new blocks + BlockPollingInterval = 1 * time.Second + // TransactionBatchSize - number of transactions to send in a batch + TransactionBatchSize = 100 + // TransactionBatchThreshold - threshold for continuing to fill a block + TransactionBatchThreshold = 50 + // InitialTransactionDelay - delay between initial transactions + InitialTransactionDelay = 10 * time.Millisecond + // OptimizedTransactionDelay - reduced delay after initial batch + OptimizedTransactionDelay = 5 * time.Millisecond + // ConfirmationDelay - delay before checking confirmations + ConfirmationDelay = 2 * time.Second + // MaxRebroadcasts - maximum number of times to rebroadcast a transaction + MaxRebroadcasts = 10 + // RetryDelay - delay before retrying failed operations + RetryDelay = 5 * time.Second + // GasPerMillion - divisor for converting gas to millions + GasPerMillion = 1_000_000.0 + // BytesPerKiB - bytes in a kibibyte + BytesPerKiB = 1024.0 + // EstimatedStateGrowthPerTransfer - estimated state growth in bytes per new recipient + EstimatedStateGrowthPerTransfer = 100 + // BloatingSummaryFileName - name of the bloating summary file + BloatingSummaryFileName = "erc20_bloating_summary.json" +) + +// ScenarioOptions defines the configuration options for the scenario +type ScenarioOptions struct { + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` + Contract string `yaml:"contract"` +} + +// DeploymentEntry represents a contract deployment from deployments.json +type DeploymentEntry map[string][]string + +// ContractBloatStats tracks unique recipients per contract +type ContractBloatStats struct { + UniqueRecipients int `json:"unique_recipients"` +} + +// BloatingSummary represents the JSON file structure +type BloatingSummary struct { + Contracts map[string]*ContractBloatStats `json:"contracts"` + TotalRecipients int `json:"total_recipients"` + LastBlockNumber string `json:"last_block_number"` + LastBlockUpdate time.Time `json:"last_block_update"` +} + +// Scenario implements the ERC20 max transfers scenario +type Scenario struct { + options ScenarioOptions + logger *logrus.Entry + walletPool *spamoor.WalletPool + + // Deployed contracts and private key + deployerPrivateKey string + deployerAddress common.Address + deployerWallet *txbuilder.Wallet // Store the wallet instance + deployedContracts []common.Address + currentRoundContract common.Address // Contract being used for current round + contractsLock sync.Mutex + + // Transfer function ABI + transferABI abi.Method + contractABI abi.ABI + + // Used addresses tracking + usedAddresses map[common.Address]bool + usedAddressesLock sync.Mutex + + // Bloating statistics tracking + contractStats map[common.Address]*ContractBloatStats + contractStatsLock sync.Mutex +} + +var ScenarioName = "erc20-max-transfers" +var ScenarioDefaultOptions = ScenarioOptions{ + BaseFee: DefaultBaseFeeGwei, + TipFee: DefaultTipFeeGwei, + Contract: "", +} +var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ + Name: ScenarioName, + Description: "Maximum ERC20 transfers per block to unique addresses", + DefaultOptions: ScenarioDefaultOptions, + NewScenario: newScenario, +} + +func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { + return &Scenario{ + logger: logger.WithField("scenario", ScenarioName), + usedAddresses: make(map[common.Address]bool), + contractStats: make(map[common.Address]*ContractBloatStats), + } +} + +func (s *Scenario) Flags(flags *pflag.FlagSet) error { + flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Max fee per gas to use in transactions (in gwei)") + flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") + flags.StringVar(&s.options.Contract, "contract", ScenarioDefaultOptions.Contract, "Specific contract address to use (default: rotate through all)") + return nil +} + +func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { + s.walletPool = walletPool + + if config != "" { + err := yaml.Unmarshal([]byte(config), &s.options) + if err != nil { + return fmt.Errorf("failed to unmarshal config: %w", err) + } + } + + // Load deployed contracts from deployments.json + err := s.loadDeployedContracts() + if err != nil { + return fmt.Errorf("failed to load deployed contracts: %w", err) + } + + // Load transfer function ABI + err = s.loadTransferABI() + if err != nil { + return fmt.Errorf("failed to load transfer ABI: %w", err) + } + + // We'll use the deployer wallet which we'll prepare in runMaxTransfersMode + s.walletPool.SetWalletCount(0) + + return nil +} + +func (s *Scenario) Config() string { + yamlBytes, _ := yaml.Marshal(&s.options) + return string(yamlBytes) +} + +// loadDeployedContracts loads contract addresses and private key from deployments.json +func (s *Scenario) loadDeployedContracts() error { + data, err := os.ReadFile("deployments.json") + if err != nil { + return fmt.Errorf("failed to read deployments.json: %w", err) + } + + var deployments DeploymentEntry + err = json.Unmarshal(data, &deployments) + if err != nil { + return fmt.Errorf("failed to parse deployments.json: %w", err) + } + + // Get the first (and only) entry + for privateKey, addresses := range deployments { + // Trim 0x prefix if present + if strings.HasPrefix(privateKey, "0x") { + privateKey = privateKey[2:] + } + s.deployerPrivateKey = privateKey + s.deployedContracts = make([]common.Address, len(addresses)) + for i, addr := range addresses { + s.deployedContracts[i] = common.HexToAddress(addr) + } + break // Only process the first entry + } + + if s.deployerPrivateKey == "" || len(s.deployedContracts) == 0 { + return fmt.Errorf("no valid deployments found in deployments.json") + } + + s.logger.Infof("Loaded %d deployed contracts from deployments.json", len(s.deployedContracts)) + + // Initialize contract stats for all deployed contracts + for _, contractAddr := range s.deployedContracts { + s.contractStats[contractAddr] = &ContractBloatStats{ + UniqueRecipients: 0, + } + } + + // If specific contract requested, validate it exists + if s.options.Contract != "" { + contractAddr := common.HexToAddress(s.options.Contract) + found := false + for _, addr := range s.deployedContracts { + if addr == contractAddr { + found = true + s.deployedContracts = []common.Address{contractAddr} // Use only this contract + break + } + } + if !found { + return fmt.Errorf("specified contract %s not found in deployments", s.options.Contract) + } + s.logger.Infof("Using specific contract: %s", contractAddr.Hex()) + } + + return nil +} + +// loadTransferABI loads the transfer function ABI from the contract +func (s *Scenario) loadTransferABI() error { + // Parse the contract ABI to get the transfer method + contractABI, err := abi.JSON(strings.NewReader(contract.ContractMetaData.ABI)) + if err != nil { + return fmt.Errorf("failed to parse contract ABI: %w", err) + } + + transferMethod, exists := contractABI.Methods["transfer"] + if !exists { + return fmt.Errorf("transfer method not found in contract ABI") + } + + s.transferABI = transferMethod + s.contractABI = contractABI + return nil +} + +// getNetworkBlockGasLimit retrieves the current block gas limit from the network +// It waits for a new block to be mined (with timeout) to ensure fresh data +func (s *Scenario) getNetworkBlockGasLimit(ctx context.Context, client *txbuilder.Client) uint64 { + // Create a timeout context for the entire operation + timeoutCtx, cancel := context.WithTimeout(ctx, BlockMiningTimeout) + defer cancel() + + // Get the current block number first + currentBlockNumber, err := client.GetEthClient().BlockNumber(timeoutCtx) + if err != nil { + s.logger.Warnf("failed to get current block number: %v, using fallback: %d", err, FallbackBlockGasLimit) + return FallbackBlockGasLimit + } + + s.logger.Debugf("waiting for new block to be mined (current: %d, timeout: %v)", currentBlockNumber, BlockMiningTimeout) + + // Wait for a new block to be mined + ticker := time.NewTicker(BlockPollingInterval) + defer ticker.Stop() + + var latestBlock *types.Block + for { + select { + case <-timeoutCtx.Done(): + s.logger.Warnf("timeout waiting for new block to be mined, using fallback: %d", FallbackBlockGasLimit) + return FallbackBlockGasLimit + case <-ticker.C: + // Check for a new block + newBlockNumber, err := client.GetEthClient().BlockNumber(timeoutCtx) + if err != nil { + s.logger.Debugf("error checking block number: %v", err) + continue + } + + // If we have a new block, get its details + if newBlockNumber > currentBlockNumber { + latestBlock, err = client.GetEthClient().BlockByNumber(timeoutCtx, nil) + if err != nil { + s.logger.Debugf("error getting latest block details: %v", err) + continue + } + s.logger.Debugf("new block mined: %d", newBlockNumber) + goto blockFound + } + } + } + +blockFound: + gasLimit := latestBlock.GasLimit() + s.logger.Debugf("network block gas limit from fresh block #%d: %d", latestBlock.NumberU64(), gasLimit) + return gasLimit +} + +// generateRecipient generates a deterministic recipient address based on index +func (s *Scenario) generateRecipient(recipientIndex uint64) common.Address { + idxBytes := make([]byte, 8) + binary.BigEndian.PutUint64(idxBytes, recipientIndex) + // Use deployer address as seed for deterministic generation + hash := sha256.Sum256(append(s.deployerAddress.Bytes(), idxBytes...)) + return common.BytesToAddress(hash[12:]) // Use last 20 bytes as address +} + +// loadBloatingSummary loads the bloating summary from file or creates a new one +func (s *Scenario) loadBloatingSummary() (*BloatingSummary, error) { + data, err := os.ReadFile(BloatingSummaryFileName) + if err != nil { + if os.IsNotExist(err) { + // File doesn't exist, return new summary + return &BloatingSummary{ + Contracts: make(map[string]*ContractBloatStats), + TotalRecipients: 0, + }, nil + } + return nil, fmt.Errorf("failed to read bloating summary: %w", err) + } + + var summary BloatingSummary + if err := json.Unmarshal(data, &summary); err != nil { + return nil, fmt.Errorf("failed to unmarshal bloating summary: %w", err) + } + + // Ensure contracts map is initialized + if summary.Contracts == nil { + summary.Contracts = make(map[string]*ContractBloatStats) + } + + return &summary, nil +} + +// saveBloatingSummary saves the bloating summary to file +func (s *Scenario) saveBloatingSummary(summary *BloatingSummary) error { + data, err := json.MarshalIndent(summary, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal bloating summary: %w", err) + } + + if err := os.WriteFile(BloatingSummaryFileName, data, 0644); err != nil { + return fmt.Errorf("failed to write bloating summary: %w", err) + } + + return nil +} + +// updateContractStats updates the statistics for a contract when a transfer is confirmed +func (s *Scenario) updateContractStats(contractAddr common.Address) { + s.contractStatsLock.Lock() + defer s.contractStatsLock.Unlock() + + stats, exists := s.contractStats[contractAddr] + if !exists { + stats = &ContractBloatStats{ + UniqueRecipients: 0, + } + s.contractStats[contractAddr] = stats + } + stats.UniqueRecipients++ +} + +// updateAndSaveBloatingSummary updates the bloating summary with current stats and saves to file +func (s *Scenario) updateAndSaveBloatingSummary(blockNumber string) error { + // Load existing summary + summary, err := s.loadBloatingSummary() + if err != nil { + return err + } + + // Update with current stats + s.contractStatsLock.Lock() + totalRecipients := 0 + for contractAddr, stats := range s.contractStats { + contractHex := contractAddr.Hex() + summary.Contracts[contractHex] = &ContractBloatStats{ + UniqueRecipients: stats.UniqueRecipients, + } + totalRecipients += stats.UniqueRecipients + } + s.contractStatsLock.Unlock() + + // Update summary metadata + summary.TotalRecipients = totalRecipients + summary.LastBlockNumber = blockNumber + summary.LastBlockUpdate = time.Now() + + // Save to file + return s.saveBloatingSummary(summary) +} + +// getContractBloatingSummaryForBlock returns a formatted string with contract bloating info for latest block +func (s *Scenario) getContractBloatingSummaryForBlock() string { + s.contractStatsLock.Lock() + defer s.contractStatsLock.Unlock() + + // Get current round contract + s.contractsLock.Lock() + currentContract := s.currentRoundContract + s.contractsLock.Unlock() + + if currentContract == (common.Address{}) { + return "No contract selected for current round" + } + + // Get stats for current contract + stats, exists := s.contractStats[currentContract] + if !exists { + return fmt.Sprintf("CONTRACT BLOATING STATUS:\n Round Contract: %s - No transfers yet", currentContract.Hex()) + } + + return fmt.Sprintf("CONTRACT BLOATING STATUS:\n Round Contract: %s - %d unique recipients", + currentContract.Hex(), stats.UniqueRecipients) +} + +// selectRandomContract randomly selects a contract from the deployed contracts +func (s *Scenario) selectRandomContract() (common.Address, error) { + s.contractsLock.Lock() + defer s.contractsLock.Unlock() + + if len(s.deployedContracts) == 0 { + return common.Address{}, fmt.Errorf("no deployed contracts available") + } + + // If only one contract, return it + if len(s.deployedContracts) == 1 { + return s.deployedContracts[0], nil + } + + // Generate random index + max := big.NewInt(int64(len(s.deployedContracts))) + n, err := rand.Int(rand.Reader, max) + if err != nil { + return common.Address{}, fmt.Errorf("failed to generate random number: %w", err) + } + + return s.deployedContracts[n.Int64()], nil +} + +func (s *Scenario) Run(ctx context.Context) error { + return s.runMaxTransfersMode(ctx) +} + +func (s *Scenario) runMaxTransfersMode(ctx context.Context) error { + s.logger.Infof("starting max transfers mode: self-adjusting to target block gas limit, continuous operation") + + // Get a client for network operations + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + + // Get the actual network block gas limit + networkGasLimit := s.getNetworkBlockGasLimit(ctx, client) + targetGas := uint64(float64(networkGasLimit) * DefaultTargetGasRatio) + + // Calculate initial transfer count based on network gas limit and known gas cost per transfer + initialTransfers := int(targetGas / ERC20TransferGasCost) + + // Dynamic transfer count - starts based on network parameters and adjusts based on actual performance + currentTransfers := initialTransfers + + // Prepare the deployer wallet if not already done + if s.deployerWallet == nil { + // Create wallet from deployer private key + deployerWallet, err := txbuilder.NewWallet(s.deployerPrivateKey) + if err != nil { + return fmt.Errorf("failed to create deployer wallet: %w", err) + } + + // Update wallet with chain info using the client + err = client.UpdateWallet(ctx, deployerWallet) + if err != nil { + return fmt.Errorf("failed to update deployer wallet: %w", err) + } + + // Store the wallet instance + s.deployerWallet = deployerWallet + s.deployerAddress = deployerWallet.GetAddress() + + s.logger.Infof("Initialized deployer wallet - Address: %s, Nonce: %d, Balance: %s ETH", + s.deployerAddress.Hex(), deployerWallet.GetNonce(), new(big.Int).Div(deployerWallet.GetBalance(), big.NewInt(1e18)).String()) + } + + var blockCounter int + var totalTransfers uint64 + var totalUniqueRecipients uint64 + + for { + select { + case <-ctx.Done(): + s.logger.Errorf("max transfers mode stopping due to context cancellation") + return ctx.Err() + default: + } + + blockCounter++ + + // Send the max transfer transactions and wait for confirmation + s.logger.Infof("════════════════ TRANSFER PHASE #%d ════════════════", blockCounter) + actualGasUsed, blockNumber, transferCount, gasPerTransfer, uniqueRecipients, err := s.sendMaxTransfers(ctx, s.deployerWallet, currentTransfers, targetGas, blockCounter, client) + if err != nil { + s.logger.Errorf("failed to send max transfers for iteration %d: %v", blockCounter, err) + time.Sleep(RetryDelay) // Wait before retry + continue + } + + // Update totals + totalTransfers += uint64(transferCount) + totalUniqueRecipients += uint64(uniqueRecipients) + + s.logger.Infof("%%%%%%%%%%%%%%%%%%%% ANALYSIS PHASE #%d %%%%%%%%%%%%%%%%%%%%", blockCounter) + + // Calculate metrics + blockGasLimit := float64(networkGasLimit) + gasUtilization := (float64(actualGasUsed) / blockGasLimit) * 100 + estimatedStateGrowth := uniqueRecipients * EstimatedStateGrowthPerTransfer + + s.logger.WithField("scenario", ScenarioName).Infof("TRANSFER METRICS - Block #%s | Transfers: %d | Unique recipients: %d | Gas used: %.2fM | Block utilization: %.2f%% | Gas/transfer: %.1f | Est. state growth: %.2f KiB", + blockNumber, transferCount, uniqueRecipients, float64(actualGasUsed)/GasPerMillion, gasUtilization, gasPerTransfer, float64(estimatedStateGrowth)/BytesPerKiB) + + // Log contract-specific bloating info + s.logger.WithField("scenario", ScenarioName).Info(s.getContractBloatingSummaryForBlock()) + + // Log cumulative metrics + s.logger.WithField("scenario", ScenarioName).Infof("CUMULATIVE TOTALS - Total transfers: %d | Total unique recipients: %d | Avg transfers/block: %.1f", + totalTransfers, totalUniqueRecipients, float64(totalTransfers)/float64(blockCounter)) + + // Update and save bloating summary + err = s.updateAndSaveBloatingSummary(blockNumber) + if err != nil { + s.logger.Warnf("Failed to update bloating summary: %v", err) + } + + // Self-adjust transfer count based on actual performance + if actualGasUsed > 0 && transferCount > 0 { + avgGasPerTransfer := float64(actualGasUsed) / float64(transferCount) + targetTransfers := int(float64(targetGas) / avgGasPerTransfer) + + // Calculate the adjustment needed + transferDifference := targetTransfers - transferCount + + if actualGasUsed < targetGas { + // We're under target, increase transfer count with a slight safety margin + newTransfers := currentTransfers + transferDifference - 1 + + if newTransfers > currentTransfers { + s.logger.Infof("Adjusting transfers: %d → %d (need %d more for target)", + currentTransfers, newTransfers, transferDifference) + currentTransfers = newTransfers + } + } else if actualGasUsed > targetGas { + // We're over target, reduce to reach max block utilization + excess := actualGasUsed - targetGas + excessTransfers := int(float64(excess) / avgGasPerTransfer) + newTransfers := currentTransfers - excessTransfers + + s.logger.Infof("Reducing transfers: %d → %d (excess: %d gas, ~%d transfers)", + currentTransfers, newTransfers, excess, excessTransfers) + currentTransfers = newTransfers + + } else { + s.logger.Infof("Target achieved! Gas Used: %d / Target: %d", actualGasUsed, targetGas) + } + } + } +} + +func (s *Scenario) sendMaxTransfers(ctx context.Context, deployerWallet *txbuilder.Wallet, targetTransfers int, targetGasLimit uint64, blockCounter int, client *txbuilder.Client) (uint64, string, int, float64, int, error) { + // Select a random contract for this round + contractForRound, err := s.selectRandomContract() + if err != nil { + return 0, "", 0, 0, 0, fmt.Errorf("failed to select contract for round: %w", err) + } + + // Update current round contract + s.contractsLock.Lock() + s.currentRoundContract = contractForRound + s.contractsLock.Unlock() + + s.logger.Infof("Selected contract for round #%d: %s", blockCounter, contractForRound.Hex()) + + // Get suggested fees or use configured values + var feeCap *big.Int + var tipCap *big.Int + + if s.options.BaseFee > 0 { + feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(GweiPerEth)) + } + if s.options.TipFee > 0 { + tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(GweiPerEth)) + } + + if feeCap == nil || tipCap == nil { + var err error + feeCap, tipCap, err = client.GetSuggestedFee(s.walletPool.GetContext()) + if err != nil { + return 0, "", 0, 0, 0, fmt.Errorf("failed to get suggested fees: %w", err) + } + } + + // Ensure minimum gas prices for inclusion + minFeeCap := new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(GweiPerEth)) + minTipCap := new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(GweiPerEth)) + + if feeCap.Cmp(minFeeCap) < 0 { + feeCap = minFeeCap + } + if tipCap.Cmp(minTipCap) < 0 { + tipCap = minTipCap + } + + // Send transfers in batches + return s.sendTransferBatch(ctx, deployerWallet, targetTransfers, targetGasLimit, blockCounter, client, feeCap, tipCap) +} + +func (s *Scenario) sendTransferBatch(ctx context.Context, wallet *txbuilder.Wallet, targetTransfers int, targetGasLimit uint64, iteration int, client *txbuilder.Client, feeCap, tipCap *big.Int) (uint64, string, int, float64, int, error) { + var confirmedCount int64 + var uniqueRecipientsCount int64 + var totalGasUsed uint64 + var lastBlockNumber string + + sentCount := 0 + recipientIndex := uint64(iteration * 1000000) // Large offset per iteration to avoid conflicts + + // Calculate approximate transactions per block based on gas limit + maxTxsPerBlock := int(targetGasLimit / ERC20TransferGasCost) + + // Track confirmations + type confirmResult struct { + gasUsed uint64 + blockNumber string + recipient common.Address + contractUsed common.Address + } + // Make channel buffered with enough capacity for all transactions + confirmChan := make(chan confirmResult, targetTransfers*2) // Double buffer to be safe + + // Send transactions + for sentCount < targetTransfers { + // Generate unique recipient address + var recipient common.Address + for { + recipient = s.generateRecipient(recipientIndex) + recipientIndex++ + + // Check if address already used + s.usedAddressesLock.Lock() + if !s.usedAddresses[recipient] { + s.usedAddresses[recipient] = true + s.usedAddressesLock.Unlock() + break + } + s.usedAddressesLock.Unlock() + } + + // Use the contract selected for this round + s.contractsLock.Lock() + contractAddr := s.currentRoundContract + s.contractsLock.Unlock() + + // Encode transfer call data + transferAmount := big.NewInt(TokenTransferAmount) + callData, err := s.contractABI.Pack("transfer", recipient, transferAmount) + if err != nil { + s.logger.Errorf("failed to pack transfer call data: %v", err) + continue + } + + // Build transaction + txMetadata := &txbuilder.TxMetadata{ + GasFeeCap: uint256.MustFromBig(feeCap), + GasTipCap: uint256.MustFromBig(tipCap), + Gas: ERC20TransferGasCost, + To: &contractAddr, + Value: uint256.NewInt(0), // No ETH value for ERC20 transfer + Data: callData, + } + + txData, err := txbuilder.DynFeeTx(txMetadata) + if err != nil { + s.logger.Errorf("failed to create tx data: %v", err) + continue + } + + tx, err := wallet.BuildDynamicFeeTx(txData) + if err != nil { + s.logger.Errorf("failed to build transaction: %v", err) + continue + } + + // Capture values for closure + capturedRecipient := recipient + capturedContract := contractAddr + + // Send transaction + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &txbuilder.SendTransactionOptions{ + Client: client, + MaxRebroadcasts: 0, // No retries to avoid duplicates + OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + if err != nil { + return // Don't log individual failures + } + if receipt != nil && receipt.Status == 1 { + atomic.AddInt64(&confirmedCount, 1) + atomic.AddInt64(&uniqueRecipientsCount, 1) + + // Update contract stats + s.updateContractStats(capturedContract) + + // Send result to channel with captured values + confirmChan <- confirmResult{ + gasUsed: receipt.GasUsed, + blockNumber: receipt.BlockNumber.String(), + recipient: capturedRecipient, + contractUsed: capturedContract, + } + } + }, + LogFn: func(client *txbuilder.Client, retry int, rebroadcast int, err error) { + // Only log actual send failures + if err != nil { + s.logger.Debugf("transfer tx send failed: %v", err) + } + }, + }) + + if err != nil { + continue + } + + sentCount++ + + // Small delay between transactions to ensure proper nonce ordering + if sentCount < TransactionBatchSize { + time.Sleep(InitialTransactionDelay) + } else if sentCount%maxTxsPerBlock < TransactionBatchThreshold { + time.Sleep(OptimizedTransactionDelay) + } + + // Add context cancellation check + select { + case <-ctx.Done(): + return 0, "", 0, 0, 0, ctx.Err() + default: + } + } + + // Wait for confirmations + s.logger.Infof("Sent %d transfer transactions, waiting for confirmations...", sentCount) + time.Sleep(ConfirmationDelay) + + // Log initial confirmation status + initialConfirmed := atomic.LoadInt64(&confirmedCount) + if initialConfirmed > 0 { + s.logger.Debugf("Already have %d confirmations before collection", initialConfirmed) + } + + // Collect results - wait for all sent transactions or timeout + confirmTimeout := time.After(30 * time.Second) + resultCount := 0 + +collectResults: + for resultCount < sentCount { + select { + case result := <-confirmChan: + totalGasUsed += result.gasUsed + lastBlockNumber = result.blockNumber + resultCount++ + + case <-confirmTimeout: + // Final check for any remaining confirmations + confirmed := atomic.LoadInt64(&confirmedCount) + s.logger.Warnf("Timeout waiting for confirmations, received %d results, %d confirmed, %d sent", resultCount, confirmed, sentCount) + break collectResults + + case <-ctx.Done(): + return 0, "", 0, 0, 0, ctx.Err() + } + } + + // Drain any remaining results from the channel (non-blocking) + for { + select { + case result := <-confirmChan: + totalGasUsed += result.gasUsed + lastBlockNumber = result.blockNumber + resultCount++ + default: + // No more results available + goto done + } + } +done: + + // Calculate metrics + confirmed := atomic.LoadInt64(&confirmedCount) + uniqueRecipients := atomic.LoadInt64(&uniqueRecipientsCount) + + // Log detailed confirmation statistics + s.logger.Debugf("Confirmation stats: sent=%d, confirmed=%d, results=%d, gas=%d", + sentCount, confirmed, resultCount, totalGasUsed) + + if confirmed == 0 { + return 0, "", 0, 0, 0, fmt.Errorf("no transfers confirmed") + } + + gasPerTransfer := float64(totalGasUsed) / float64(confirmed) + + return totalGasUsed, lastBlockNumber, int(confirmed), gasPerTransfer, int(uniqueRecipients), nil +} From 183e3a773e3146a7bc54e84f4201c308714a8861 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Wed, 18 Jun 2025 22:25:40 +0200 Subject: [PATCH 26/39] chore(erc20_max_transfers): --- .../statebloat/erc20_max_transfers/README.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/scenarios/statebloat/erc20_max_transfers/README.md b/scenarios/statebloat/erc20_max_transfers/README.md index f1f349b1..2767073b 100644 --- a/scenarios/statebloat/erc20_max_transfers/README.md +++ b/scenarios/statebloat/erc20_max_transfers/README.md @@ -23,14 +23,6 @@ The scenario uses deployed StateBloatToken contracts from `deployments.json` to - `--tipfee`: Max tip per gas in gwei (default: 5) - `--contract`: Specific contract address to use (default: rotate through all) -### YAML Configuration - -```yaml -basefee: 10 -tipfee: 5 -contract: "" # Empty string means use all contracts -``` - ## How It Works 1. **Initialization**: @@ -64,13 +56,6 @@ Each successful transfer creates: ## Output -The scenario logs detailed metrics for each block: -- Number of transfers sent and confirmed -- Unique recipients created -- Gas usage and block utilization -- Estimated state growth -- Cumulative totals - Recipient addresses are saved to `recipients.json` with: - Address - Block number From eb03b45bc8c2439fea2bedd5b93be9ae46ad337c Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 00:42:19 +0200 Subject: [PATCH 27/39] various fixes & improvements for `statebloat-eoa-delegation` scenario --- scenarios/scenarios.go | 8 +- .../eoa_delegation/eoa_delegation.go | 907 +++++++----------- spamoor/walletpool.go | 5 + 3 files changed, 361 insertions(+), 559 deletions(-) diff --git a/scenarios/scenarios.go b/scenarios/scenarios.go index a2ed4320..19e4791e 100644 --- a/scenarios/scenarios.go +++ b/scenarios/scenarios.go @@ -16,10 +16,8 @@ import ( "github.com/ethpandaops/spamoor/scenarios/gasburnertx" "github.com/ethpandaops/spamoor/scenarios/geastx" "github.com/ethpandaops/spamoor/scenarios/setcodetx" - contractdeploy "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy" - eoadelegation "github.com/ethpandaops/spamoor/scenarios/statebloat/eoa_delegation" + sbeoadelegation "github.com/ethpandaops/spamoor/scenarios/statebloat/eoa_delegation" "github.com/ethpandaops/spamoor/scenarios/storagespam" - uniswapswaps "github.com/ethpandaops/spamoor/scenarios/uniswap-swaps" "github.com/ethpandaops/spamoor/scenarios/wallets" "github.com/ethpandaops/spamoor/scenarios/xentoken" @@ -42,13 +40,11 @@ var ScenarioDescriptors = []*scenario.Descriptor{ &gasburnertx.ScenarioDescriptor, &geastx.ScenarioDescriptor, &setcodetx.ScenarioDescriptor, + &sbeoadelegation.ScenarioDescriptor, &storagespam.ScenarioDescriptor, &uniswapswaps.ScenarioDescriptor, &wallets.ScenarioDescriptor, - &contractdeploy.ScenarioDescriptor, - &eoadelegation.ScenarioDescriptor, &xentoken.ScenarioDescriptor, - } // GetScenario finds and returns a scenario descriptor by name. diff --git a/scenarios/statebloat/eoa_delegation/eoa_delegation.go b/scenarios/statebloat/eoa_delegation/eoa_delegation.go index 8f6cf269..b4d16cc5 100644 --- a/scenarios/statebloat/eoa_delegation/eoa_delegation.go +++ b/scenarios/statebloat/eoa_delegation/eoa_delegation.go @@ -1,4 +1,4 @@ -package eoadelegation +package sbeoadelegation import ( "context" @@ -21,7 +21,7 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/pflag" - "github.com/ethpandaops/spamoor/scenariotypes" + "github.com/ethpandaops/spamoor/scenario" "github.com/ethpandaops/spamoor/spamoor" "github.com/ethpandaops/spamoor/txbuilder" ) @@ -91,6 +91,8 @@ type ScenarioOptions struct { BaseFee uint64 `yaml:"base_fee"` TipFee uint64 `yaml:"tip_fee"` CodeAddr string `yaml:"code_addr"` + EoaFile string `yaml:"eoa_file"` + LogTxs bool `yaml:"log_txs"` } // EOAEntry represents a funded EOA account @@ -107,27 +109,24 @@ type Scenario struct { // FIFO queue for funded accounts eoaQueue []EOAEntry eoaQueueMutex sync.Mutex - - // Semaphore for worker control - workerSemaphore chan struct{} - workerDone chan struct{} - workerWg sync.WaitGroup } -var ScenarioName = "eoa-delegation" +var ScenarioName = "statebloat-eoa-delegation" var ScenarioDefaultOptions = ScenarioOptions{ BaseFee: 20, TipFee: 2, CodeAddr: "", + EoaFile: "", + LogTxs: false, } -var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ +var ScenarioDescriptor = scenario.Descriptor{ Name: ScenarioName, Description: "Maximum state bloating via EIP-7702 EOA delegations", DefaultOptions: ScenarioDefaultOptions, NewScenario: newScenario, } -func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { +func newScenario(logger logrus.FieldLogger) scenario.Scenario { return &Scenario{ logger: logger.WithField("scenario", ScenarioName), } @@ -137,14 +136,16 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Max fee per gas to use in transactions (in gwei)") flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") flags.StringVar(&s.options.CodeAddr, "code-addr", ScenarioDefaultOptions.CodeAddr, "Code delegation target address to use for transactions (default: ecrecover precompile)") + flags.StringVar(&s.options.EoaFile, "eoa-file", ScenarioDefaultOptions.EoaFile, "File to write EOAs to") + flags.BoolVar(&s.options.LogTxs, "log-txs", ScenarioDefaultOptions.LogTxs, "Log transactions") return nil } -func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { - s.walletPool = walletPool +func (s *Scenario) Init(options *scenario.Options) error { + s.walletPool = options.WalletPool - if config != "" { - err := yaml.Unmarshal([]byte(config), &s.options) + if options.Config != "" { + err := yaml.Unmarshal([]byte(options.Config), &s.options) if err != nil { return fmt.Errorf("failed to unmarshal config: %w", err) } @@ -154,17 +155,20 @@ func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { s.logger.Infof("no --code-addr specified, using ecrecover precompile as delegate: %s", common.HexToAddress("0x0000000000000000000000000000000000000001")) } - // In max-bloating mode, use 1 wallet (the root wallet) - s.walletPool.SetWalletCount(1) + // In max-bloating mode, use 100 wallets for funding delegators + s.walletPool.SetWalletCount(100) + s.walletPool.SetRefillAmount(uint256.NewInt(0).Mul(uint256.NewInt(20), uint256.NewInt(1000000000000000000))) // 20 ETH + s.walletPool.SetRefillBalance(uint256.NewInt(0).Mul(uint256.NewInt(10), uint256.NewInt(1000000000000000000))) // 10 ETH + + // register well known wallets + s.walletPool.AddWellKnownWallet(&spamoor.WellKnownWalletConfig{ + Name: "bloater", + RefillAmount: uint256.NewInt(0).Mul(uint256.NewInt(20), uint256.NewInt(1000000000000000000)), // 20 ETH + RefillBalance: uint256.NewInt(0).Mul(uint256.NewInt(10), uint256.NewInt(1000000000000000000)), // 10 ETH + }) // Initialize FIFO queue and worker for EOA management s.eoaQueue = make([]EOAEntry, 0) - s.workerSemaphore = make(chan struct{}, 1) // Buffered channel for semaphore - s.workerDone = make(chan struct{}) - - // Start the worker goroutine for writing EOAs to file - s.workerWg.Add(1) - go s.eoaWorker() return nil } @@ -174,128 +178,27 @@ func (s *Scenario) Config() string { return string(yamlBytes) } -// getNetworkBlockGasLimit retrieves the current block gas limit from the network -// It waits for a new block to be mined (with timeout) to ensure fresh data -func (s *Scenario) getNetworkBlockGasLimit(ctx context.Context, client *txbuilder.Client) uint64 { - // Create a timeout context for the entire operation - timeoutCtx, cancel := context.WithTimeout(ctx, BlockMiningTimeout) - defer cancel() - - // Get the current block number first - currentBlockNumber, err := client.GetEthClient().BlockNumber(timeoutCtx) - if err != nil { - s.logger.Warnf("failed to get current block number: %v, using fallback: %d", err, FallbackBlockGasLimit) - return FallbackBlockGasLimit - } - - s.logger.Debugf("waiting for new block to be mined (current: %d, timeout: %v)", currentBlockNumber, BlockMiningTimeout) - - // Wait for a new block to be mined - ticker := time.NewTicker(BlockPollingInterval) - defer ticker.Stop() - - var latestBlock *types.Block - for { - select { - case <-timeoutCtx.Done(): - s.logger.Warnf("timeout waiting for new block to be mined, using fallback: %d", FallbackBlockGasLimit) - return FallbackBlockGasLimit - case <-ticker.C: - // Check for a new block - newBlockNumber, err := client.GetEthClient().BlockNumber(timeoutCtx) - if err != nil { - s.logger.Debugf("error checking block number: %v", err) - continue - } - - // If we have a new block, get its details - if newBlockNumber > currentBlockNumber { - latestBlock, err = client.GetEthClient().BlockByNumber(timeoutCtx, nil) - if err != nil { - s.logger.Debugf("error getting latest block details: %v", err) - continue - } - s.logger.Debugf("new block mined: %d", newBlockNumber) - goto blockFound - } - } - } - -blockFound: - gasLimit := latestBlock.GasLimit() - s.logger.Debugf("network block gas limit from fresh block #%d: %d", latestBlock.NumberU64(), gasLimit) - return gasLimit +func (s *Scenario) prepareDelegator(delegatorIndex uint64) (*spamoor.Wallet, error) { + delegatorSeed := make([]byte, 8) + binary.BigEndian.PutUint64(delegatorSeed, delegatorIndex) + delegatorSeed = append(delegatorSeed, s.walletPool.GetWalletSeed()...) + delegatorSeed = append(delegatorSeed, s.walletPool.GetRootWallet().GetWallet().GetAddress().Bytes()...) + childKey := sha256.Sum256(delegatorSeed) + return spamoor.NewWallet(fmt.Sprintf("%x", childKey)) } func (s *Scenario) Run(ctx context.Context) error { - // This scenario only runs in max-bloating mode - return s.runMaxBloatingMode(ctx) -} - -func (s *Scenario) prepareDelegator(delegatorIndex uint64) (*txbuilder.Wallet, error) { - idxBytes := make([]byte, 8) - binary.BigEndian.PutUint64(idxBytes, delegatorIndex) - childKey := sha256.Sum256(append(common.FromHex(s.walletPool.GetRootWallet().GetAddress().Hex()), idxBytes...)) - return txbuilder.NewWallet(fmt.Sprintf("%x", childKey)) -} - -func (s *Scenario) buildMaxBloatingAuthorizations(targetCount int, iteration int) []types.SetCodeAuthorization { - authorizations := make([]types.SetCodeAuthorization, 0, targetCount) - - // Use a fixed delegate contract address for maximum efficiency - // In max bloating mode, we want all EOAs to delegate to the same existing contract - // to benefit from reduced gas costs (PER_AUTH_BASE_COST vs PER_EMPTY_ACCOUNT_COST) - // Precompiles are ideal as they're guaranteed to exist with code on all networks - var codeAddr common.Address - if s.options.CodeAddr != "" { - codeAddr = common.HexToAddress(s.options.CodeAddr) - } else { - // Default to using the ecrecover precompile (0x1) as delegate target - codeAddr = common.HexToAddress("0x0000000000000000000000000000000000000001") - } - - chainId := s.walletPool.GetRootWallet().GetChainId().Uint64() - - for i := 0; i < targetCount; i++ { - // Create a unique delegator for each authorization - // Include iteration counter to ensure different addresses for each iteration - delegatorIndex := uint64(iteration*targetCount + i) - - delegator, err := s.prepareDelegator(delegatorIndex) - if err != nil { - s.logger.Errorf("could not prepare delegator %v: %v", delegatorIndex, err) - continue - } - - // Each EOA uses auth_nonce = 0 (assuming first EIP-7702 operation) - // This creates maximum new state as each EOA gets its first delegation - authorization := types.SetCodeAuthorization{ - ChainID: *uint256.NewInt(chainId), - Address: codeAddr, - Nonce: 0, // First delegation for each EOA - } - - // Sign the authorization with the delegator's private key - signedAuth, err := types.SignSetCode(delegator.GetPrivateKey(), authorization) - if err != nil { - s.logger.Errorf("could not sign set code authorization for delegator %v: %v", delegatorIndex, err) - continue - } - - authorizations = append(authorizations, signedAuth) - } - - return authorizations -} - -func (s *Scenario) runMaxBloatingMode(ctx context.Context) error { s.logger.Infof("starting max bloating mode: self-adjusting to target block gas limit, continuous operation") - // Get a client for network operations - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + go s.eoaWorker(ctx) // Get the actual network block gas limit - networkGasLimit := s.getNetworkBlockGasLimit(ctx, client) + networkGasLimit, err := s.walletPool.GetTxPool().GetCurrentGasLimitWithInit() + if err != nil { + s.logger.Errorf("failed to get current gas limit: %v", err) + return err + } + targetGas := uint64(float64(networkGasLimit) * DefaultTargetGasRatio) // Calculate initial authorization count based on network gas limit and known gas cost per authorization @@ -320,19 +223,13 @@ func (s *Scenario) runMaxBloatingMode(ctx context.Context) error { // For subsequent iterations, funding happens after analysis if blockCounter == 1 { s.logger.Infof("════════════════ INITIAL FUNDING PHASE ════════════════") - confirmedCount, err := s.fundMaxBloatingDelegators(ctx, currentAuthorizations, blockCounter, networkGasLimit) + _, err := s.fundMaxBloatingDelegators(ctx, currentAuthorizations, blockCounter, networkGasLimit) if err != nil { s.logger.Errorf("failed to fund delegators for initial iteration: %v", err) time.Sleep(RetryDelay) // Wait before retry blockCounter-- // Retry the same iteration continue } - - // Wait for funding transactions to be confirmed and included in blocks - err = s.waitForFundingConfirmations(ctx, confirmedCount) - if err != nil { - s.logger.Errorf("error waiting for funding confirmations: %v", err) - } } // Send the max bloating transaction and wait for confirmation @@ -344,9 +241,6 @@ func (s *Scenario) runMaxBloatingMode(ctx context.Context) error { continue } - // Open semaphore (green light) during analysis phase to allow worker to process EOA queue - s.openWorkerSemaphore() - s.logger.Infof("%%%%%%%%%%%%%%%%%%%% ANALYSIS PHASE #%d %%%%%%%%%%%%%%%%%%%%", blockCounter) // Calculate total bytes written to state @@ -393,34 +287,20 @@ func (s *Scenario) runMaxBloatingMode(ctx context.Context) error { // Now fund delegators for the next iteration (except on the last iteration) // This ensures funding happens AFTER bloating transactions are confirmed s.logger.Infof("════════════════ FUNDING PHASE #%d (for next iteration) ════════════════", blockCounter) - confirmedCount, err := s.fundMaxBloatingDelegators(ctx, currentAuthorizations, blockCounter+1, networkGasLimit) + _, err = s.fundMaxBloatingDelegators(ctx, currentAuthorizations, blockCounter+1, networkGasLimit) if err != nil { s.logger.Errorf("failed to fund delegators for next iteration: %v", err) // Don't fail the entire loop, just log the error and continue } - - // Wait for funding transactions to be confirmed before next bloating phase - if confirmedCount > 0 { - err = s.waitForFundingConfirmations(ctx, confirmedCount) - if err != nil { - s.logger.Errorf("error waiting for funding confirmations: %v", err) - } - } } } func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount int, iteration int, gasLimit uint64) (int64, error) { - // Close semaphore (red light) during funding phase - s.closeWorkerSemaphore() - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") if client == nil { return 0, fmt.Errorf("no client available for funding delegators") } - // Use root wallet since we set child wallet count to 0 in max-bloating mode - wallet := s.walletPool.GetRootWallet() - // Get suggested fees for funding transactions var feeCap *big.Int var tipCap *big.Int @@ -452,32 +332,34 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in fundingAmount := uint256.NewInt(1) var confirmedCount int64 - sentCount := uint64(0) - delegatorIndex := uint64(iteration * FundingIterationOffset) // Large offset per iteration to avoid conflicts + wg := sync.WaitGroup{} - // Calculate approximate transactions per block based on gas limit - // Standard transfer = BaseTransferCost gas. - var maxTxsPerBlock = gasLimit / uint64(BaseTransferCost) + delegatorIndexBase := uint64(iteration * FundingIterationOffset) // Large offset per iteration to avoid conflicts - for { - // Check if we have enough confirmed transactions - confirmed := atomic.LoadInt64(&confirmedCount) - if confirmed >= int64(targetCount) { - // We have minimum required, but let's check if we should fill the current block - // If we've sent transactions recently, wait a bit to see if block gets filled - if sentCount > 0 && (sentCount%TransactionBatchSize) > TransactionBatchThreshold { - // Continue to fill the block - } else { - break - } + fundNextDelegator := func(ctx context.Context, txIdx uint64, onComplete func()) (*types.Transaction, *spamoor.Client, *spamoor.Wallet, error) { + wallet := s.walletPool.GetWallet(spamoor.SelectWalletByIndex, int(txIdx)) + if wallet == nil { + return nil, nil, nil, fmt.Errorf("no wallet available for funding") + } + + client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") + if client == nil { + return nil, nil, nil, fmt.Errorf("no client available for funding delegators") } - // Generate unique delegator address + delegatorIndex := delegatorIndexBase + txIdx + transactionSubmitted := false + + defer func() { + if !transactionSubmitted { + onComplete() + } + }() + delegator, err := s.prepareDelegator(delegatorIndex) if err != nil { s.logger.Errorf("could not prepare delegator %v for funding: %v", delegatorIndex, err) - delegatorIndex++ - continue + return nil, nil, nil, err } // Build funding transaction @@ -492,22 +374,25 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in }) if err != nil { s.logger.Errorf("failed to build funding tx for delegator %d: %v", delegatorIndex, err) - delegatorIndex++ - continue + return nil, nil, nil, err } tx, err := wallet.BuildDynamicFeeTx(txData) if err != nil { s.logger.Errorf("failed to build funding transaction for delegator %d: %v", delegatorIndex, err) - delegatorIndex++ - continue + return nil, nil, nil, err } // Send funding transaction with no retries to avoid duplicates - err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &txbuilder.SendTransactionOptions{ - Client: client, - MaxRebroadcasts: 0, // No retries to avoid duplicates + transactionSubmitted = true + wg.Add(1) + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + Client: client, + Rebroadcast: false, // No retries to avoid duplicates OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + defer wg.Done() + defer onComplete() + if err != nil { return // Don't log individual failures } @@ -520,7 +405,7 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in // No progress logging - only log when target is reached } }, - LogFn: func(client *txbuilder.Client, retry int, rebroadcast int, err error) { + LogFn: func(client *spamoor.Client, retry int, rebroadcast int, err error) { // Only log actual send failures, not confirmation failures if err != nil { s.logger.Debugf("funding tx send failed: %v", err) @@ -528,100 +413,60 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in }, }) - if err != nil { - delegatorIndex++ - continue - } - - sentCount++ - delegatorIndex++ - - // Check if we should continue filling the block - confirmed = atomic.LoadInt64(&confirmedCount) - if confirmed >= int64(targetCount) && sentCount%maxTxsPerBlock < TransactionBatchSize { - // We have enough confirmed and we're at the end of a block cycle, stop for now - break - } - - // Small delay between transactions to ensure proper nonce ordering - // Reduce delay as we get more efficient - if sentCount < TransactionBatchSize { - time.Sleep(InitialTransactionDelay) - } else { - time.Sleep(OptimizedTransactionDelay) - } - - // Add context cancellation check - select { - case <-ctx.Done(): - return 0, ctx.Err() - default: - } + return tx, client, wallet, err } - // Wait for any remaining transactions to be included - time.Sleep(FundingConfirmationDelay) + // Calculate approximate transactions per block based on gas limit + // Standard transfer = BaseTransferCost gas. + maxTxsPerBlock := gasLimit / uint64(BaseTransferCost) + + scenario.RunTransactionScenario(ctx, scenario.TransactionScenarioOptions{ + TotalCount: uint64(targetCount), + Throughput: maxTxsPerBlock * 2, + MaxPending: maxTxsPerBlock * 2, + WalletPool: s.walletPool, + ProcessNextTxFn: func(ctx context.Context, txIdx uint64, onComplete func()) (func(), error) { + logger := s.logger + tx, client, wallet, err := fundNextDelegator(ctx, txIdx, onComplete) + if client != nil { + logger = logger.WithField("rpc", client.GetName()) + } + if tx != nil { + logger = logger.WithField("nonce", tx.Nonce()) + } + if wallet != nil { + logger = logger.WithField("wallet", s.walletPool.GetWalletName(wallet.GetAddress())) + } + + return func() { + if err != nil { + logger.Warnf("could not send transaction: %v", err) + } else if s.options.LogTxs { + logger.Infof("sent tx #%6d: %v", txIdx+1, tx.Hash().String()) + } else { + logger.Debugf("sent tx #%6d: %v", txIdx+1, tx.Hash().String()) + } + }, err + }, + }) // Return the confirmed count + wg.Wait() confirmed := atomic.LoadInt64(&confirmedCount) return confirmed, nil } -// waitForFundingConfirmations waits for funding transactions to be confirmed by monitoring for new blocks -func (s *Scenario) waitForFundingConfirmations(ctx context.Context, targetConfirmations int64) error { - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") - if client == nil { - return fmt.Errorf("no client available for monitoring blocks") - } - - s.logger.Infof("Waiting for funding transactions to be confirmed (expecting ~%d confirmations)...", targetConfirmations) - - // Get the starting block number - startBlock, err := client.GetEthClient().BlockNumber(ctx) - if err != nil { - return fmt.Errorf("failed to get starting block number: %w", err) - } - - // Monitor until we see at least 1 new block to ensure funding txs are included - ticker := time.NewTicker(1 * time.Second) - defer ticker.Stop() - - blocksWaited := uint64(0) - for { - select { - case <-ctx.Done(): - return ctx.Err() - case <-ticker.C: - // Check current block number - currentBlock, err := client.GetEthClient().BlockNumber(ctx) - if err != nil { - s.logger.Debugf("Error getting block number: %v", err) - continue - } - - // If we have new blocks - if currentBlock > startBlock { - blocksWaited = currentBlock - startBlock - s.logger.Debugf("New block %d mined (%d blocks since funding started)", currentBlock, blocksWaited) - - // Wait for at least 1 block to ensure funding transactions are included - if blocksWaited >= 1 { - s.logger.Infof("Funding transactions should be confirmed (waited %d blocks)", blocksWaited) - return nil - } - } - } - } -} - func (s *Scenario) sendMaxBloatingTransaction(ctx context.Context, targetAuthorizations int, targetGasLimit uint64, blockCounter int) (uint64, string, int, float64, float64, string, error) { client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") if client == nil { return 0, "", 0, 0, 0, "", fmt.Errorf("no client available for sending max bloating transaction") } - // Use root wallet since we set child wallet count to 0 in max-bloating mode - wallet := s.walletPool.GetRootWallet() + // Use bloater wallet + wallet := s.walletPool.GetWellKnownWallet("bloater") + if wallet == nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("no bloater wallet available") + } // Get suggested fees or use configured values var feeCap *big.Int @@ -674,8 +519,110 @@ func (s *Scenario) sendMaxBloatingTransaction(ctx context.Context, targetAuthori } } +// buildMaxBloatingAuthorizations builds the authorizations for the max bloating transaction +func (s *Scenario) buildMaxBloatingAuthorizations(targetCount int, iteration int) []types.SetCodeAuthorization { + authorizations := make([]types.SetCodeAuthorization, 0, targetCount) + + // Use a fixed delegate contract address for maximum efficiency + // In max bloating mode, we want all EOAs to delegate to the same existing contract + // to benefit from reduced gas costs (PER_AUTH_BASE_COST vs PER_EMPTY_ACCOUNT_COST) + // Precompiles are ideal as they're guaranteed to exist with code on all networks + var codeAddr common.Address + if s.options.CodeAddr != "" { + codeAddr = common.HexToAddress(s.options.CodeAddr) + } else { + // Default to using the ecrecover precompile (0x1) as delegate target + codeAddr = common.HexToAddress("0x0000000000000000000000000000000000000001") + } + + chainId := s.walletPool.GetChainId() + + for i := 0; i < targetCount; i++ { + // Create a unique delegator for each authorization + // Include iteration counter to ensure different addresses for each iteration + delegatorIndex := uint64(iteration*targetCount + i) + + delegator, err := s.prepareDelegator(delegatorIndex) + if err != nil { + s.logger.Errorf("could not prepare delegator %v: %v", delegatorIndex, err) + continue + } + + // Each EOA uses auth_nonce = 0 (assuming first EIP-7702 operation) + // This creates maximum new state as each EOA gets its first delegation + authorization := types.SetCodeAuthorization{ + ChainID: *uint256.MustFromBig(chainId), + Address: codeAddr, + Nonce: 0, // First delegation for each EOA + } + + // Sign the authorization with the delegator's private key + signedAuth, err := types.SignSetCode(delegator.GetPrivateKey(), authorization) + if err != nil { + s.logger.Errorf("could not sign set code authorization for delegator %v: %v", delegatorIndex, err) + continue + } + + authorizations = append(authorizations, signedAuth) + } + + return authorizations +} + +// splitAuthorizationsBatches splits authorizations into batches that fit within transaction size limit +func (s *Scenario) splitAuthorizationsBatches(authorizations []types.SetCodeAuthorization, callDataSize int) [][]types.SetCodeAuthorization { + if len(authorizations) == 0 { + return [][]types.SetCodeAuthorization{authorizations} + } + + // To get closer to 128KiB limit, we need to adjust our estimate + // Using a safety factor of 0.95 to stay just under the limit + targetSize := MaxTransactionSize * TransactionSizeSafetyFactor / 100 // Safety margin + + maxAuthsPerTx := (targetSize - TransactionBaseOverhead - callDataSize) / ActualBytesPerAuth + if maxAuthsPerTx <= 0 { + s.logger.Warnf("Transaction call data too large, using minimal batch size of 1") + maxAuthsPerTx = 1 + } + + // If all authorizations fit in one transaction, return as single batch + if len(authorizations) <= maxAuthsPerTx { + estimatedSize := s.calculateTransactionSize(len(authorizations), callDataSize) + s.logger.Infof("All %d authorizations fit in single transaction (estimated size: %d bytes)", len(authorizations), estimatedSize) + return [][]types.SetCodeAuthorization{authorizations} + } + + // Split into multiple batches + var batches [][]types.SetCodeAuthorization + for i := 0; i < len(authorizations); i += maxAuthsPerTx { + end := i + maxAuthsPerTx + if end > len(authorizations) { + end = len(authorizations) + } + batch := authorizations[i:end] + batches = append(batches, batch) + } + + s.logger.Infof("Split %d authorizations into %d batches (max %d auths per batch, target size: %.2f KiB)", + len(authorizations), len(batches), maxAuthsPerTx, float64(targetSize)/BytesPerKiB) + return batches +} + +// calculateTransactionSize estimates the serialized size of a transaction with given authorizations +func (s *Scenario) calculateTransactionSize(authCount int, callDataSize int) int { + // Estimation based on empirical data and RLP encoding structure: + // - Base transaction overhead: ~200 bytes + // - Each SetCodeAuthorization: ~94 bytes (based on actual observed data) + // - Call data: variable size + // - Additional RLP encoding overhead: ~50 bytes + + baseSize := TransactionBaseOverhead + callDataSize + TransactionExtraOverhead + authSize := authCount * ActualBytesPerAuth + return baseSize + authSize +} + // sendSingleMaxBloatingTransaction sends a single transaction (original logic) -func (s *Scenario) sendSingleMaxBloatingTransaction(ctx context.Context, authorizations []types.SetCodeAuthorization, txCallData []byte, feeCap, tipCap *big.Int, amount *uint256.Int, toAddr common.Address, targetGasLimit uint64, wallet *txbuilder.Wallet, client *txbuilder.Client) (uint64, string, int, float64, float64, string, error) { +func (s *Scenario) sendSingleMaxBloatingTransaction(ctx context.Context, authorizations []types.SetCodeAuthorization, txCallData []byte, feeCap, tipCap *big.Int, amount *uint256.Int, toAddr common.Address, targetGasLimit uint64, wallet *spamoor.Wallet, client *spamoor.Client) (uint64, string, int, float64, float64, string, error) { txData, err := txbuilder.SetCodeTx(&txbuilder.TxMetadata{ GasFeeCap: uint256.MustFromBig(feeCap), GasTipCap: uint256.MustFromBig(tipCap), @@ -706,79 +653,22 @@ func (s *Scenario) sendSingleMaxBloatingTransaction(ctx context.Context, authori s.logger.WithField("scenario", "eoa-delegation").Infof("MAX BLOATING TX SIZE: %d bytes (%.2f KiB) | Limit: %d bytes (%.1f KiB) | %d authorizations | Exceeds limit: %v", txSize, sizeKiB, MaxTransactionSize, limitKiB, len(authorizations), exceedsLimit) - // Use channels to capture transaction results - resultChan := make(chan struct { - gasUsed uint64 - blockNumber string - authCount int - gasPerAuth float64 - gasPerByte float64 - gweiTotalFee string - err error - }, 1) + wg := sync.WaitGroup{} + wg.Add(1) + + var txreceipt *types.Receipt + var txerr error // Send the transaction - err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &txbuilder.SendTransactionOptions{ - Client: client, - MaxRebroadcasts: 10, - RebroadcastInterval: 120 * time.Second, // Default rebroadcast interval + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + Client: client, + Rebroadcast: true, OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { - if err != nil { - s.logger.WithField("rpc", client.GetName()).Errorf("max bloating tx failed: %v", err) - resultChan <- struct { - gasUsed uint64 - blockNumber string - authCount int - gasPerAuth float64 - gasPerByte float64 - gweiTotalFee string - err error - }{0, "", 0, 0, 0, "", err} - return - } - if receipt == nil { - resultChan <- struct { - gasUsed uint64 - blockNumber string - authCount int - gasPerAuth float64 - gasPerByte float64 - gweiTotalFee string - err error - }{0, "", 0, 0, 0, "", fmt.Errorf("no receipt received")} - return - } - - effectiveGasPrice := receipt.EffectiveGasPrice - if effectiveGasPrice == nil { - effectiveGasPrice = big.NewInt(0) - } - feeAmount := new(big.Int).Mul(effectiveGasPrice, big.NewInt(int64(receipt.GasUsed))) - totalAmount := new(big.Int).Add(tx.Value(), feeAmount) - wallet.SubBalance(totalAmount) - - gweiTotalFee := new(big.Int).Div(feeAmount, big.NewInt(1000000000)) - - // Calculate efficiency metrics - authCount := len(authorizations) - gasPerAuth := float64(receipt.GasUsed) / float64(authCount) - gasPerByte := gasPerAuth / EstimatedBytesPerAuth - - resultChan <- struct { - gasUsed uint64 - blockNumber string - authCount int - gasPerAuth float64 - gasPerByte float64 - gweiTotalFee string - err error - }{receipt.GasUsed, receipt.BlockNumber.String(), - authCount, - gasPerAuth, - gasPerByte, - gweiTotalFee.String(), nil} + txreceipt = receipt + txerr = err + wg.Done() }, - LogFn: func(client *txbuilder.Client, retry int, rebroadcast int, err error) { + LogFn: func(client *spamoor.Client, retry int, rebroadcast int, err error) { logger := s.logger.WithField("rpc", client.GetName()) if retry > 0 { logger = logger.WithField("retry", retry) @@ -800,12 +690,36 @@ func (s *Scenario) sendSingleMaxBloatingTransaction(ctx context.Context, authori } // Wait for transaction confirmation - result := <-resultChan - return result.gasUsed, result.blockNumber, result.authCount, result.gasPerAuth, result.gasPerByte, result.gweiTotalFee, result.err + wg.Wait() + + if txerr != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to send max bloating transaction: %w", txerr) + } + + if txreceipt == nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("no receipt received") + } + + effectiveGasPrice := txreceipt.EffectiveGasPrice + if effectiveGasPrice == nil { + effectiveGasPrice = big.NewInt(0) + } + feeAmount := new(big.Int).Mul(effectiveGasPrice, big.NewInt(int64(txreceipt.GasUsed))) + totalAmount := new(big.Int).Add(tx.Value(), feeAmount) + wallet.SubBalance(totalAmount) + + gweiTotalFee := new(big.Int).Div(feeAmount, big.NewInt(1000000000)) + + // Calculate efficiency metrics + authCount := len(authorizations) + gasPerAuth := float64(txreceipt.GasUsed) / float64(authCount) + gasPerByte := gasPerAuth / EstimatedBytesPerAuth + + return txreceipt.GasUsed, txreceipt.BlockNumber.String(), authCount, gasPerAuth, gasPerByte, gweiTotalFee.String(), nil } // sendBatchedMaxBloatingTransactions sends multiple transactions when size limit is exceeded -func (s *Scenario) sendBatchedMaxBloatingTransactions(ctx context.Context, batches [][]types.SetCodeAuthorization, txCallData []byte, feeCap, tipCap *big.Int, amount *uint256.Int, toAddr common.Address, targetGasLimit uint64, wallet *txbuilder.Wallet, client *txbuilder.Client) (uint64, string, int, float64, float64, string, error) { +func (s *Scenario) sendBatchedMaxBloatingTransactions(ctx context.Context, batches [][]types.SetCodeAuthorization, txCallData []byte, feeCap, tipCap *big.Int, amount *uint256.Int, toAddr common.Address, targetGasLimit uint64, wallet *spamoor.Wallet, client *spamoor.Client) (uint64, string, int, float64, float64, string, error) { // Aggregate results var totalGasUsed uint64 var totalAuthCount int @@ -813,144 +727,114 @@ func (s *Scenario) sendBatchedMaxBloatingTransactions(ctx context.Context, batch var lastBlockNumber string // Create result channels for all batches upfront - resultChans := make([]chan struct { - gasUsed uint64 - blockNumber string - authCount int - gweiTotalFee string - err error - }, len(batches)) + wg := sync.WaitGroup{} + wg.Add(len(batches)) + + txreceipts := make([]*types.Receipt, len(batches)) + txerrs := make([]error, len(batches)) // Send all batches quickly with minimal delay to increase chance of same block inclusion for batchIndex, batch := range batches { - // Create result channel for this batch - resultChans[batchIndex] = make(chan struct { - gasUsed uint64 - blockNumber string - authCount int - gweiTotalFee string - err error - }, 1) - - // Calculate appropriate gas limit for this batch based on authorization count - // Each authorization needs ~26000 gas, plus some overhead for the transaction itself - batchGasLimit := uint64(len(batch))*GasPerAuthorization + BaseTransferCost + uint64(len(txCallData)*GasPerCallDataByte) - - // Ensure we don't exceed the target limit per transaction - maxGasPerTx := targetGasLimit - if batchGasLimit > maxGasPerTx { - batchGasLimit = maxGasPerTx - } - // Build the transaction for this batch - txData, err := txbuilder.SetCodeTx(&txbuilder.TxMetadata{ - GasFeeCap: uint256.MustFromBig(feeCap), - GasTipCap: uint256.MustFromBig(tipCap), - Gas: batchGasLimit, - To: &toAddr, - Value: amount, - Data: txCallData, - AuthList: batch, - }) - if err != nil { - return 0, "", 0, 0, 0, "", fmt.Errorf("failed to build batch %d transaction metadata: %w", batchIndex+1, err) - } + err := func(batchIndex int, batch []types.SetCodeAuthorization) error { + // Calculate appropriate gas limit for this batch based on authorization count + // Each authorization needs ~26000 gas, plus some overhead for the transaction itself + batchGasLimit := uint64(len(batch))*GasPerAuthorization + BaseTransferCost + uint64(len(txCallData)*GasPerCallDataByte) - tx, err := wallet.BuildSetCodeTx(txData) - if err != nil { - return 0, "", 0, 0, 0, "", fmt.Errorf("failed to build batch %d transaction: %w", batchIndex+1, err) - } + // Ensure we don't exceed the target limit per transaction + maxGasPerTx := targetGasLimit + if batchGasLimit > maxGasPerTx { + batchGasLimit = maxGasPerTx + } - // Send the transaction immediately without waiting for confirmation - resultChan := resultChans[batchIndex] - err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &txbuilder.SendTransactionOptions{ - Client: client, - MaxRebroadcasts: MaxRebroadcasts, - RebroadcastInterval: 120 * time.Second, // Default rebroadcast interval - OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { - if err != nil { - s.logger.WithField("rpc", client.GetName()).Errorf("batch %d tx failed: %v", batchIndex+1, err) - resultChan <- struct { - gasUsed uint64 - blockNumber string - authCount int - gweiTotalFee string - err error - }{0, "", 0, "", err} - return - } - if receipt == nil { - resultChan <- struct { - gasUsed uint64 - blockNumber string - authCount int - gweiTotalFee string - err error - }{0, "", 0, "", fmt.Errorf("batch %d: no receipt received", batchIndex+1)} - return - } + // Build the transaction for this batch + txData, err := txbuilder.SetCodeTx(&txbuilder.TxMetadata{ + GasFeeCap: uint256.MustFromBig(feeCap), + GasTipCap: uint256.MustFromBig(tipCap), + Gas: batchGasLimit, + To: &toAddr, + Value: amount, + Data: txCallData, + AuthList: batch, + }) + if err != nil { + return fmt.Errorf("failed to build batch %d transaction metadata: %w", batchIndex+1, err) + } - effectiveGasPrice := receipt.EffectiveGasPrice - if effectiveGasPrice == nil { - effectiveGasPrice = big.NewInt(0) - } - feeAmount := new(big.Int).Mul(effectiveGasPrice, big.NewInt(int64(receipt.GasUsed))) - totalAmount := new(big.Int).Add(tx.Value(), feeAmount) - wallet.SubBalance(totalAmount) - - gweiTotalFee := new(big.Int).Div(feeAmount, big.NewInt(GweiPerEth)) - - resultChan <- struct { - gasUsed uint64 - blockNumber string - authCount int - gweiTotalFee string - err error - }{receipt.GasUsed, receipt.BlockNumber.String(), len(batch), gweiTotalFee.String(), nil} - }, - LogFn: func(client *txbuilder.Client, retry int, rebroadcast int, err error) { - logger := s.logger.WithField("rpc", client.GetName()) - if err != nil { - logger.Errorf("failed sending batch %d tx: %v", batchIndex+1, err) - } else if retry > 0 || rebroadcast > 0 { - logger.Debugf("successfully sent batch %d tx (retry/rebroadcast)", batchIndex+1) - } - }, - }) + tx, err := wallet.BuildSetCodeTx(txData) + if err != nil { + return fmt.Errorf("failed to build batch %d transaction: %w", batchIndex+1, err) + } + + // Send the transaction immediately without waiting for confirmation + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + Client: client, + Rebroadcast: true, + OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + txreceipts[batchIndex] = receipt + txerrs[batchIndex] = err + wg.Done() + }, + LogFn: func(client *spamoor.Client, retry int, rebroadcast int, err error) { + logger := s.logger.WithField("rpc", client.GetName()) + if err != nil { + logger.Errorf("failed sending batch %d tx: %v", batchIndex+1, err) + } else if retry > 0 || rebroadcast > 0 { + logger.Debugf("successfully sent batch %d tx (retry/rebroadcast)", batchIndex+1) + } + }, + }) + + if err != nil { + wallet.ResetPendingNonce(ctx, client) + return fmt.Errorf("failed to send batch %d transaction: %w", batchIndex+1, err) + } + + return nil + }(batchIndex, batch) if err != nil { - wallet.ResetPendingNonce(ctx, client) return 0, "", 0, 0, 0, "", fmt.Errorf("failed to send batch %d transaction: %w", batchIndex+1, err) } - - // No delay between batches - send as fast as possible to ensure same block inclusion } // Now wait for all batch confirmations + wg.Wait() + blockNumbers := make(map[string]int) // Track which blocks contain our transactions batchDetails := make([]string, len(batches)) // Store details of each batch for batchIndex := range batches { - result := <-resultChans[batchIndex] - if result.err != nil { - return 0, "", 0, 0, 0, "", fmt.Errorf("batch %d failed: %w", batchIndex+1, result.err) + if txerrs[batchIndex] != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("batch %d failed: %w", batchIndex+1, txerrs[batchIndex]) + } + + txreceipt := txreceipts[batchIndex] + if txreceipt == nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("batch %d: no receipt received", batchIndex+1) } + effectiveGasPrice := txreceipt.EffectiveGasPrice + if effectiveGasPrice == nil { + effectiveGasPrice = big.NewInt(0) + } + feeAmount := new(big.Int).Mul(effectiveGasPrice, big.NewInt(int64(txreceipt.GasUsed))) + + gweiTotalFee := new(big.Int).Div(feeAmount, big.NewInt(GweiPerEth)) + // Aggregate successful results - totalGasUsed += result.gasUsed - totalAuthCount += result.authCount - lastBlockNumber = result.blockNumber + totalGasUsed += txreceipt.GasUsed + totalAuthCount += len(batches[batchIndex]) + lastBlockNumber = txreceipt.BlockNumber.String() // Track block numbers - blockNumbers[result.blockNumber]++ + blockNumbers[txreceipt.BlockNumber.String()]++ // Parse and add fee - if feeGwei, ok := new(big.Int).SetString(result.gweiTotalFee, 10); ok { - totalFees.Add(totalFees, feeGwei) - } + totalFees.Add(totalFees, gweiTotalFee) // Store batch details - batchGasInM := float64(result.gasUsed) / GasPerMillion - gasPerAuthBatch := float64(result.gasUsed) / float64(result.authCount) + batchGasInM := float64(txreceipt.GasUsed) / GasPerMillion + gasPerAuthBatch := float64(txreceipt.GasUsed) / float64(len(batches[batchIndex])) gasPerByteBatch := gasPerAuthBatch / EstimatedBytesPerAuth // Calculate tx size based on authorizations @@ -958,7 +842,7 @@ func (s *Scenario) sendBatchedMaxBloatingTransactions(ctx context.Context, batch sizeKiB := float64(txSize) / BytesPerKiB batchDetails[batchIndex] = fmt.Sprintf("Batch %d/%d: %.2fM gas, %d auths, %.2f KiB, %.2f gas/auth, %.2f gas/byte, (block %s)", - batchIndex+1, len(batches), batchGasInM, result.authCount, sizeKiB, gasPerAuthBatch, gasPerByteBatch, result.blockNumber) + batchIndex+1, len(batches), batchGasInM, len(batches[batchIndex]), sizeKiB, gasPerAuthBatch, gasPerByteBatch, txreceipt.BlockNumber.String()) } // Calculate aggregate metrics @@ -998,17 +882,13 @@ Aggregate Metrics: } // eoaWorker runs in a separate goroutine and writes funded EOAs to EOAs.json -// when the semaphore is open (green). It sleeps when the semaphore is closed (red). -func (s *Scenario) eoaWorker() { - defer s.workerWg.Done() - +func (s *Scenario) eoaWorker(ctx context.Context) { for { select { - case <-s.workerDone: + case <-ctx.Done(): // Shutdown signal received return - case <-s.workerSemaphore: - // Semaphore is green, process the queue + case <-time.After(30 * time.Second): // flush every 30 seconds s.processEOAQueue() } } @@ -1016,20 +896,20 @@ func (s *Scenario) eoaWorker() { // processEOAQueue drains the EOA queue and writes entries to EOAs.json func (s *Scenario) processEOAQueue() { - for { - // Check if there are items in the queue - s.eoaQueueMutex.Lock() - if len(s.eoaQueue) == 0 { - s.eoaQueueMutex.Unlock() - return // Queue is empty, exit processing - } - - // Dequeue all items (FIFO) - eoasToWrite := make([]EOAEntry, len(s.eoaQueue)) - copy(eoasToWrite, s.eoaQueue) - s.eoaQueue = s.eoaQueue[:0] // Clear the queue + // Check if there are items in the queue + s.eoaQueueMutex.Lock() + if len(s.eoaQueue) == 0 { s.eoaQueueMutex.Unlock() + return // Queue is empty, exit processing + } + + // Dequeue all items (FIFO) + eoasToWrite := make([]EOAEntry, len(s.eoaQueue)) + copy(eoasToWrite, s.eoaQueue) + s.eoaQueue = s.eoaQueue[:0] // Clear the queue + s.eoaQueueMutex.Unlock() + if s.options.EoaFile != "" { // Write to file err := s.writeEOAsToFile(eoasToWrite) if err != nil { @@ -1040,7 +920,6 @@ func (s *Scenario) processEOAQueue() { s.eoaQueueMutex.Unlock() return } - } } @@ -1087,81 +966,3 @@ func (s *Scenario) addEOAToQueue(address, privateKey string) { s.eoaQueue = append(s.eoaQueue, entry) } - -// openWorkerSemaphore opens the semaphore (green light) allowing the worker to process -func (s *Scenario) openWorkerSemaphore() { - select { - case s.workerSemaphore <- struct{}{}: - // Semaphore opened successfully - default: - // Semaphore already open, do nothing - } -} - -// closeWorkerSemaphore closes the semaphore (red light) putting the worker to sleep -func (s *Scenario) closeWorkerSemaphore() { - select { - case <-s.workerSemaphore: - // Semaphore closed successfully - default: - // Semaphore already closed, do nothing - } -} - -// shutdownWorker signals the worker to stop and waits for it to finish -func (s *Scenario) shutdownWorker() { - close(s.workerDone) - s.workerWg.Wait() -} - -// calculateTransactionSize estimates the serialized size of a transaction with given authorizations -func (s *Scenario) calculateTransactionSize(authCount int, callDataSize int) int { - // Estimation based on empirical data and RLP encoding structure: - // - Base transaction overhead: ~200 bytes - // - Each SetCodeAuthorization: ~94 bytes (based on actual observed data) - // - Call data: variable size - // - Additional RLP encoding overhead: ~50 bytes - - baseSize := TransactionBaseOverhead + callDataSize + TransactionExtraOverhead - authSize := authCount * ActualBytesPerAuth - return baseSize + authSize -} - -// splitAuthorizationsBatches splits authorizations into batches that fit within transaction size limit -func (s *Scenario) splitAuthorizationsBatches(authorizations []types.SetCodeAuthorization, callDataSize int) [][]types.SetCodeAuthorization { - if len(authorizations) == 0 { - return [][]types.SetCodeAuthorization{authorizations} - } - - // To get closer to 128KiB limit, we need to adjust our estimate - // Using a safety factor of 0.95 to stay just under the limit - targetSize := MaxTransactionSize * TransactionSizeSafetyFactor / 100 // Safety margin - - maxAuthsPerTx := (targetSize - TransactionBaseOverhead - callDataSize) / ActualBytesPerAuth - if maxAuthsPerTx <= 0 { - s.logger.Warnf("Transaction call data too large, using minimal batch size of 1") - maxAuthsPerTx = 1 - } - - // If all authorizations fit in one transaction, return as single batch - if len(authorizations) <= maxAuthsPerTx { - estimatedSize := s.calculateTransactionSize(len(authorizations), callDataSize) - s.logger.Infof("All %d authorizations fit in single transaction (estimated size: %d bytes)", len(authorizations), estimatedSize) - return [][]types.SetCodeAuthorization{authorizations} - } - - // Split into multiple batches - var batches [][]types.SetCodeAuthorization - for i := 0; i < len(authorizations); i += maxAuthsPerTx { - end := i + maxAuthsPerTx - if end > len(authorizations) { - end = len(authorizations) - } - batch := authorizations[i:end] - batches = append(batches, batch) - } - - s.logger.Infof("Split %d authorizations into %d batches (max %d auths per batch, target size: %.2f KiB)", - len(authorizations), len(batches), maxAuthsPerTx, float64(targetSize)/BytesPerKiB) - return batches -} diff --git a/spamoor/walletpool.go b/spamoor/walletpool.go index e0abf53f..7332864e 100644 --- a/spamoor/walletpool.go +++ b/spamoor/walletpool.go @@ -184,6 +184,11 @@ func (pool *WalletPool) SetRefillBalance(balance *uint256.Int) { pool.config.RefillBalance = balance } +// GetWalletSeed returns the seed used for deterministic wallet generation. +func (pool *WalletPool) GetWalletSeed() string { + return pool.config.WalletSeed +} + // SetWalletSeed sets the seed used for deterministic wallet generation. // The same seed will always generate the same set of wallets. func (pool *WalletPool) SetWalletSeed(seed string) { From 26b8bad652a3373a81aec61c7271a320b3f85fa7 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 01:13:02 +0200 Subject: [PATCH 28/39] various fixes for `statebloat-rand-sstore` scenario --- .../README.md | 0 .../rand_sstore/contract/.gitignore | 3 + .../contract/SSTOREStorageBloater.go | 224 +++++++++++++++++ .../contract/SSTOREStorageBloater.sol | 0 .../rand_sstore/contract/compile.sh | 35 +++ .../rand_sstore_bloater.go | 203 +++++++++------- .../contract/SSTOREStorageBloater.go | 225 ------------------ 7 files changed, 375 insertions(+), 315 deletions(-) rename scenarios/statebloat/{rand_sstore_bloater => rand_sstore}/README.md (100%) create mode 100644 scenarios/statebloat/rand_sstore/contract/.gitignore create mode 100644 scenarios/statebloat/rand_sstore/contract/SSTOREStorageBloater.go rename scenarios/statebloat/{rand_sstore_bloater => rand_sstore}/contract/SSTOREStorageBloater.sol (100%) create mode 100755 scenarios/statebloat/rand_sstore/contract/compile.sh rename scenarios/statebloat/{rand_sstore_bloater => rand_sstore}/rand_sstore_bloater.go (70%) delete mode 100644 scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.go diff --git a/scenarios/statebloat/rand_sstore_bloater/README.md b/scenarios/statebloat/rand_sstore/README.md similarity index 100% rename from scenarios/statebloat/rand_sstore_bloater/README.md rename to scenarios/statebloat/rand_sstore/README.md diff --git a/scenarios/statebloat/rand_sstore/contract/.gitignore b/scenarios/statebloat/rand_sstore/contract/.gitignore new file mode 100644 index 00000000..f9096e53 --- /dev/null +++ b/scenarios/statebloat/rand_sstore/contract/.gitignore @@ -0,0 +1,3 @@ +*.output.json +*.bin +*.abi \ No newline at end of file diff --git a/scenarios/statebloat/rand_sstore/contract/SSTOREStorageBloater.go b/scenarios/statebloat/rand_sstore/contract/SSTOREStorageBloater.go new file mode 100644 index 00000000..6defd74e --- /dev/null +++ b/scenarios/statebloat/rand_sstore/contract/SSTOREStorageBloater.go @@ -0,0 +1,224 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contract + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// SSTOREStorageBloaterMetaData contains all meta data concerning the SSTOREStorageBloater contract. +var SSTOREStorageBloaterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"createSlots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5060f48061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063e3b393a414602d575b600080fd5b603c603836600460a7565b603e565b005b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed816001430340421860005b8281101560a0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84838301098055600101606a565b5050505050565b60006020828403121560b7578081fd5b503591905056fea264697066735822122079e4ae597ac68792390217bfee59415f78d7e370132ab6590720d9f7898a50be64736f6c63430008000033", +} + +// SSTOREStorageBloaterABI is the input ABI used to generate the binding from. +// Deprecated: Use SSTOREStorageBloaterMetaData.ABI instead. +var SSTOREStorageBloaterABI = SSTOREStorageBloaterMetaData.ABI + +// SSTOREStorageBloaterBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SSTOREStorageBloaterMetaData.Bin instead. +var SSTOREStorageBloaterBin = SSTOREStorageBloaterMetaData.Bin + +// DeploySSTOREStorageBloater deploys a new Ethereum contract, binding an instance of SSTOREStorageBloater to it. +func DeploySSTOREStorageBloater(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SSTOREStorageBloater, error) { + parsed, err := SSTOREStorageBloaterMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SSTOREStorageBloaterBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &SSTOREStorageBloater{SSTOREStorageBloaterCaller: SSTOREStorageBloaterCaller{contract: contract}, SSTOREStorageBloaterTransactor: SSTOREStorageBloaterTransactor{contract: contract}, SSTOREStorageBloaterFilterer: SSTOREStorageBloaterFilterer{contract: contract}}, nil +} + +// SSTOREStorageBloater is an auto generated Go binding around an Ethereum contract. +type SSTOREStorageBloater struct { + SSTOREStorageBloaterCaller // Read-only binding to the contract + SSTOREStorageBloaterTransactor // Write-only binding to the contract + SSTOREStorageBloaterFilterer // Log filterer for contract events +} + +// SSTOREStorageBloaterCaller is an auto generated read-only Go binding around an Ethereum contract. +type SSTOREStorageBloaterCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SSTOREStorageBloaterTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SSTOREStorageBloaterTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SSTOREStorageBloaterFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SSTOREStorageBloaterFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SSTOREStorageBloaterSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type SSTOREStorageBloaterSession struct { + Contract *SSTOREStorageBloater // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SSTOREStorageBloaterCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type SSTOREStorageBloaterCallerSession struct { + Contract *SSTOREStorageBloaterCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// SSTOREStorageBloaterTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type SSTOREStorageBloaterTransactorSession struct { + Contract *SSTOREStorageBloaterTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SSTOREStorageBloaterRaw is an auto generated low-level Go binding around an Ethereum contract. +type SSTOREStorageBloaterRaw struct { + Contract *SSTOREStorageBloater // Generic contract binding to access the raw methods on +} + +// SSTOREStorageBloaterCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SSTOREStorageBloaterCallerRaw struct { + Contract *SSTOREStorageBloaterCaller // Generic read-only contract binding to access the raw methods on +} + +// SSTOREStorageBloaterTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SSTOREStorageBloaterTransactorRaw struct { + Contract *SSTOREStorageBloaterTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewSSTOREStorageBloater creates a new instance of SSTOREStorageBloater, bound to a specific deployed contract. +func NewSSTOREStorageBloater(address common.Address, backend bind.ContractBackend) (*SSTOREStorageBloater, error) { + contract, err := bindSSTOREStorageBloater(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SSTOREStorageBloater{SSTOREStorageBloaterCaller: SSTOREStorageBloaterCaller{contract: contract}, SSTOREStorageBloaterTransactor: SSTOREStorageBloaterTransactor{contract: contract}, SSTOREStorageBloaterFilterer: SSTOREStorageBloaterFilterer{contract: contract}}, nil +} + +// NewSSTOREStorageBloaterCaller creates a new read-only instance of SSTOREStorageBloater, bound to a specific deployed contract. +func NewSSTOREStorageBloaterCaller(address common.Address, caller bind.ContractCaller) (*SSTOREStorageBloaterCaller, error) { + contract, err := bindSSTOREStorageBloater(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SSTOREStorageBloaterCaller{contract: contract}, nil +} + +// NewSSTOREStorageBloaterTransactor creates a new write-only instance of SSTOREStorageBloater, bound to a specific deployed contract. +func NewSSTOREStorageBloaterTransactor(address common.Address, transactor bind.ContractTransactor) (*SSTOREStorageBloaterTransactor, error) { + contract, err := bindSSTOREStorageBloater(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SSTOREStorageBloaterTransactor{contract: contract}, nil +} + +// NewSSTOREStorageBloaterFilterer creates a new log filterer instance of SSTOREStorageBloater, bound to a specific deployed contract. +func NewSSTOREStorageBloaterFilterer(address common.Address, filterer bind.ContractFilterer) (*SSTOREStorageBloaterFilterer, error) { + contract, err := bindSSTOREStorageBloater(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SSTOREStorageBloaterFilterer{contract: contract}, nil +} + +// bindSSTOREStorageBloater binds a generic wrapper to an already deployed contract. +func bindSSTOREStorageBloater(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := SSTOREStorageBloaterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SSTOREStorageBloater *SSTOREStorageBloaterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SSTOREStorageBloater.Contract.SSTOREStorageBloaterCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SSTOREStorageBloater *SSTOREStorageBloaterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SSTOREStorageBloater.Contract.SSTOREStorageBloaterTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SSTOREStorageBloater *SSTOREStorageBloaterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SSTOREStorageBloater.Contract.SSTOREStorageBloaterTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SSTOREStorageBloater *SSTOREStorageBloaterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SSTOREStorageBloater.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SSTOREStorageBloater *SSTOREStorageBloaterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SSTOREStorageBloater.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SSTOREStorageBloater *SSTOREStorageBloaterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SSTOREStorageBloater.Contract.contract.Transact(opts, method, params...) +} + +// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. +// +// Solidity: function createSlots(uint256 count) returns() +func (_SSTOREStorageBloater *SSTOREStorageBloaterTransactor) CreateSlots(opts *bind.TransactOpts, count *big.Int) (*types.Transaction, error) { + return _SSTOREStorageBloater.contract.Transact(opts, "createSlots", count) +} + +// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. +// +// Solidity: function createSlots(uint256 count) returns() +func (_SSTOREStorageBloater *SSTOREStorageBloaterSession) CreateSlots(count *big.Int) (*types.Transaction, error) { + return _SSTOREStorageBloater.Contract.CreateSlots(&_SSTOREStorageBloater.TransactOpts, count) +} + +// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. +// +// Solidity: function createSlots(uint256 count) returns() +func (_SSTOREStorageBloater *SSTOREStorageBloaterTransactorSession) CreateSlots(count *big.Int) (*types.Transaction, error) { + return _SSTOREStorageBloater.Contract.CreateSlots(&_SSTOREStorageBloater.TransactOpts, count) +} diff --git a/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.sol b/scenarios/statebloat/rand_sstore/contract/SSTOREStorageBloater.sol similarity index 100% rename from scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.sol rename to scenarios/statebloat/rand_sstore/contract/SSTOREStorageBloater.sol diff --git a/scenarios/statebloat/rand_sstore/contract/compile.sh b/scenarios/statebloat/rand_sstore/contract/compile.sh new file mode 100755 index 00000000..4c5e0591 --- /dev/null +++ b/scenarios/statebloat/rand_sstore/contract/compile.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +compile_contract() { + local workdir=$1 + local solc_version=$2 + local solc_args=$3 + local contract_file=$4 + local contract_name=$5 + + if [ -z "$contract_name" ]; then + contract_name="$contract_file" + fi + + #echo "docker run --rm -v $workdir:/contracts ethereum/solc:$solc_version /contracts/$contract_file.sol --combined-json abi,bin $solc_args" + local contract_json=$(docker run --rm -v $workdir:/contracts ethereum/solc:$solc_version /contracts/$contract_file.sol --combined-json abi,bin $solc_args) + + local contract_abi=$(echo "$contract_json" | jq -r '.contracts["/contracts/'$contract_file'.sol:'$contract_name'"].abi') + if [ "$contract_abi" == "null" ]; then + contract_abi=$(echo "$contract_json" | jq -r '.contracts["contracts/'$contract_file'.sol:'$contract_name'"].abi') + fi + + local contract_bin=$(echo "$contract_json" | jq -r '.contracts["/contracts/'$contract_file'.sol:'$contract_name'"].bin') + if [ "$contract_bin" == "null" ]; then + contract_bin=$(echo "$contract_json" | jq -r '.contracts["contracts/'$contract_file'.sol:'$contract_name'"].bin') + fi + + echo "$contract_abi" > $contract_name.abi + echo "$contract_bin" > $contract_name.bin + abigen --bin=./$contract_name.bin --abi=./$contract_name.abi --pkg=contract --out=$contract_name.go --type $contract_name + rm $contract_name.bin $contract_name.abi + echo "$contract_json" | jq > $contract_name.output.json +} + +# SSTOREStorageBloater +compile_contract "$(pwd)" 0.8.0 "--optimize --optimize-runs 999999" SSTOREStorageBloater diff --git a/scenarios/statebloat/rand_sstore_bloater/rand_sstore_bloater.go b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go similarity index 70% rename from scenarios/statebloat/rand_sstore_bloater/rand_sstore_bloater.go rename to scenarios/statebloat/rand_sstore/rand_sstore_bloater.go index e7708ccc..7308d0b2 100644 --- a/scenarios/statebloat/rand_sstore_bloater/rand_sstore_bloater.go +++ b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go @@ -1,4 +1,4 @@ -package randsstorebloater +package sbrandsstore import ( "context" @@ -14,21 +14,18 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/holiman/uint256" "github.com/sirupsen/logrus" "github.com/spf13/pflag" "gopkg.in/yaml.v3" - "github.com/ethpandaops/spamoor/scenarios/statebloat/rand_sstore_bloater/contract" - "github.com/ethpandaops/spamoor/scenariotypes" + "github.com/ethpandaops/spamoor/scenario" + "github.com/ethpandaops/spamoor/scenarios/statebloat/rand_sstore/contract" "github.com/ethpandaops/spamoor/spamoor" + "github.com/ethpandaops/spamoor/txbuilder" ) -//go:embed contract/SSTOREStorageBloater.abi -var contractABIBytes []byte - -//go:embed contract/SSTOREStorageBloater.bin -var contractBytecodeHex []byte - // Constants for SSTORE operations const ( // Base Ethereum transaction cost @@ -48,9 +45,6 @@ const ( // Safety margins and multipliers GasLimitSafetyMargin = 0.99 // Use 99% of block gas limit (1% margin for gas price variations) - - // Deployment tracking file - DeploymentFileName = "deployments_sstore_bloating.json" ) // BlockInfo stores block information for each storage round @@ -68,8 +62,9 @@ type DeploymentData struct { type DeploymentFile map[string]*DeploymentData // key is contract address type ScenarioOptions struct { - BaseFee uint64 `yaml:"base_fee"` - TipFee uint64 `yaml:"tip_fee"` + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` + DeploymentsFile string `yaml:"deployments_file"` } type Scenario struct { @@ -80,38 +75,33 @@ type Scenario struct { // Contract state contractAddress common.Address contractABI abi.ABI - contractInstance *contract.Contract // Generated contract binding + contractInstance *contract.SSTOREStorageBloater // Generated contract binding isDeployed bool deployMutex sync.Mutex // Scenario state totalSlots uint64 // Total number of slots created - cycleCount uint64 // Number of complete create/update cycles roundNumber uint64 // Current round number for SSTORE bloating // Adaptive gas tracking actualGasPerNewSlotIteration uint64 // Dynamically adjusted based on actual usage successfulSlotCounts map[uint64]bool // Track successful slot counts to avoid retries - - // Cached values - chainID *big.Int - chainIDOnce sync.Once - chainIDError error } -var ScenarioName = "rand_sstore_bloater" +var ScenarioName = "statebloat-rand-sstore" var ScenarioDefaultOptions = ScenarioOptions{ - BaseFee: 10, // 10 gwei default - TipFee: 2, // 2 gwei default + BaseFee: 10, // 10 gwei default + TipFee: 2, // 2 gwei default + DeploymentsFile: "", } -var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ +var ScenarioDescriptor = scenario.Descriptor{ Name: ScenarioName, Description: "Maximum state bloat via SSTORE operations using curve25519 prime dispersion", DefaultOptions: ScenarioDefaultOptions, NewScenario: newScenario, } -func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { +func newScenario(logger logrus.FieldLogger) scenario.Scenario { return &Scenario{ logger: logger.WithField("scenario", ScenarioName), actualGasPerNewSlotIteration: GasPerNewSlotIteration, // Start with estimated values @@ -122,24 +112,33 @@ func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Base fee per gas in gwei") flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Tip fee per gas in gwei") + flags.StringVar(&s.options.DeploymentsFile, "deployments-file", ScenarioDefaultOptions.DeploymentsFile, "Deployments file") return nil } -func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { - s.walletPool = walletPool +func (s *Scenario) Init(options *scenario.Options) error { + s.walletPool = options.WalletPool - if config != "" { - err := yaml.Unmarshal([]byte(config), &s.options) + if options.Config != "" { + err := yaml.Unmarshal([]byte(options.Config), &s.options) if err != nil { return fmt.Errorf("failed to unmarshal config: %w", err) } } - // Use only root wallet for simplicity s.walletPool.SetWalletCount(1) + s.walletPool.SetRefillAmount(uint256.NewInt(0).Mul(uint256.NewInt(20), uint256.NewInt(1000000000000000000))) // 20 ETH + s.walletPool.SetRefillBalance(uint256.NewInt(0).Mul(uint256.NewInt(10), uint256.NewInt(1000000000000000000))) // 10 ETH + + // register well known wallets + s.walletPool.AddWellKnownWallet(&spamoor.WellKnownWalletConfig{ + Name: "deployer", + RefillAmount: uint256.NewInt(2000000000000000000), // 2 ETH + RefillBalance: uint256.NewInt(1000000000000000000), // 1 ETH + }) // Parse contract ABI - parsedABI, err := abi.JSON(strings.NewReader(string(contractABIBytes))) + parsedABI, err := abi.JSON(strings.NewReader(string(contract.SSTOREStorageBloaterMetaData.ABI))) if err != nil { return fmt.Errorf("failed to parse contract ABI: %w", err) } @@ -154,8 +153,12 @@ func (s *Scenario) Config() string { } // loadDeploymentFile loads the deployment tracking file or creates an empty one -func loadDeploymentFile() (DeploymentFile, error) { - data, err := os.ReadFile(DeploymentFileName) +func (s *Scenario) loadDeploymentFile() (DeploymentFile, error) { + if s.options.DeploymentsFile == "" { + return make(DeploymentFile), nil + } + + data, err := os.ReadFile(s.options.DeploymentsFile) if err != nil { if os.IsNotExist(err) { // File doesn't exist, return empty map @@ -173,31 +176,23 @@ func loadDeploymentFile() (DeploymentFile, error) { } // saveDeploymentFile saves the deployment tracking file -func saveDeploymentFile(deployments DeploymentFile) error { +func (s *Scenario) saveDeploymentFile(deployments DeploymentFile) error { + if s.options.DeploymentsFile == "" { + return nil + } + data, err := json.MarshalIndent(deployments, "", " ") if err != nil { return fmt.Errorf("failed to marshal deployment file: %w", err) } - if err := os.WriteFile(DeploymentFileName, data, 0644); err != nil { + if err := os.WriteFile(s.options.DeploymentsFile, data, 0644); err != nil { return fmt.Errorf("failed to write deployment file: %w", err) } return nil } -func (s *Scenario) getChainID(ctx context.Context) (*big.Int, error) { - s.chainIDOnce.Do(func() { - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, "") - if client == nil { - s.chainIDError = fmt.Errorf("no client available for chain ID") - return - } - s.chainID, s.chainIDError = client.GetChainId(ctx) - }) - return s.chainID, s.chainIDError -} - func (s *Scenario) deployContract(ctx context.Context) error { s.deployMutex.Lock() defer s.deployMutex.Unlock() @@ -213,67 +208,102 @@ func (s *Scenario) deployContract(ctx context.Context) error { return fmt.Errorf("no client available") } - wallet := s.walletPool.GetRootWallet() + wallet := s.walletPool.GetWellKnownWallet("deployer") if wallet == nil { return fmt.Errorf("no wallet available") } - chainID, err := s.getChainID(ctx) - if err != nil { - return err + var feeCap *big.Int + var tipCap *big.Int + + if s.options.BaseFee > 0 { + feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) + } + if s.options.TipFee > 0 { + tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) } - auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), chainID) - if err != nil { - return fmt.Errorf("failed to create transactor: %w", err) + if feeCap == nil || tipCap == nil { + var err error + feeCap, tipCap, err = client.GetSuggestedFee(s.walletPool.GetContext()) + if err != nil { + return nil + } } - // Set gas parameters - auth.GasLimit = EstimatedDeployGas - auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) - auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) + if feeCap.Cmp(big.NewInt(1000000000)) < 0 { + feeCap = big.NewInt(1000000000) + } + if tipCap.Cmp(big.NewInt(1000000000)) < 0 { + tipCap = big.NewInt(1000000000) + } + + tx, err := wallet.BuildBoundTx(ctx, &txbuilder.TxMetadata{ + GasFeeCap: uint256.MustFromBig(feeCap), + GasTipCap: uint256.MustFromBig(tipCap), + Gas: 2000000, + Value: uint256.NewInt(0), + }, func(transactOpts *bind.TransactOpts) (*types.Transaction, error) { + _, deployTx, _, err := contract.DeploySSTOREStorageBloater(transactOpts, client.GetEthClient()) + return deployTx, err + }) - // Deploy contract using generated bindings - address, tx, contractInstance, err := contract.DeployContract(auth, client.GetEthClient()) if err != nil { - return fmt.Errorf("failed to deploy contract: %w", err) + return err } - s.logger.WithField("tx", tx.Hash().Hex()).Info("Contract deployment transaction sent") - - // Wait for deployment - receipt, err := bind.WaitMined(ctx, client.GetEthClient(), tx) + var txReceipt *types.Receipt + var txErr error + txWg := sync.WaitGroup{} + txWg.Add(1) + + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + Client: client, + Rebroadcast: true, + OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + defer func() { + txWg.Done() + }() + + txErr = err + txReceipt = receipt + }, + }) if err != nil { - return fmt.Errorf("failed to wait for deployment: %w", err) + return err } - if receipt.Status != 1 { - return fmt.Errorf("contract deployment failed") + txWg.Wait() + if txErr != nil { + return err } - s.contractAddress = address - s.contractInstance = contractInstance + s.contractAddress = txReceipt.ContractAddress + s.contractInstance, err = contract.NewSSTOREStorageBloater(s.contractAddress, client.GetEthClient()) + if err != nil { + return err + } s.isDeployed = true // No need to reset nonce - the wallet manager handles it automatically // Track deployment in JSON file - deployments, err := loadDeploymentFile() + deployments, err := s.loadDeploymentFile() if err != nil { s.logger.Warnf("failed to load deployment file: %v", err) deployments = make(DeploymentFile) } // Initialize deployment data for this contract - deployments[address.Hex()] = &DeploymentData{ + deployments[s.contractAddress.Hex()] = &DeploymentData{ StorageRounds: []BlockInfo{}, } - if err := saveDeploymentFile(deployments); err != nil { + if err := s.saveDeploymentFile(deployments); err != nil { s.logger.Warnf("failed to save deployment file: %v", err) } - s.logger.WithField("address", address.Hex()).Info("SSTOREStorageBloater contract deployed successfully") + s.logger.WithField("address", s.contractAddress.Hex()).Info("SSTOREStorageBloater contract deployed successfully") return nil } @@ -303,15 +333,13 @@ func (s *Scenario) Run(ctx context.Context) error { default: } - // Get current block gas limit - latestBlock, err := client.GetEthClient().BlockByNumber(ctx, nil) + blockGasLimit, err := s.walletPool.GetTxPool().GetCurrentGasLimitWithInit() if err != nil { - s.logger.Warnf("failed to get latest block: %v", err) + s.logger.Warnf("failed to get current gas limit: %v", err) time.Sleep(5 * time.Second) continue } - blockGasLimit := latestBlock.GasLimit() targetGas := uint64(float64(blockGasLimit) * GasLimitSafetyMargin) // Never stop spamming SSTORE operations. @@ -340,18 +368,13 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo return fmt.Errorf("no client available") } - wallet := s.walletPool.GetRootWallet() + wallet := s.walletPool.GetWallet(spamoor.SelectWalletByIndex, 0) if wallet == nil { return fmt.Errorf("no wallet available") } // Create transaction options - chainID, err := s.getChainID(ctx) - if err != nil { - return err - } - - auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), chainID) + auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), s.walletPool.GetChainId()) if err != nil { return fmt.Errorf("failed to create transactor: %w", err) } @@ -402,7 +425,7 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo s.logger.Warnf("failed to get previous block info: %v", err) } else { // Track this storage round in deployment file - deployments, err := loadDeploymentFile() + deployments, err := s.loadDeploymentFile() if err != nil { s.logger.Warnf("failed to load deployment file: %v", err) } else if deployments != nil { @@ -413,8 +436,8 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo BlockNumber: prevBlockNumber, Timestamp: prevBlock.Time(), }) - - if err := saveDeploymentFile(deployments); err != nil { + + if err := s.saveDeploymentFile(deployments); err != nil { s.logger.Warnf("failed to save deployment file: %v", err) } } @@ -423,7 +446,7 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo // Calculate MB written in this transaction (64 bytes per slot: 32 byte key + 32 byte value) mbWrittenThisTx := float64(slotsToCreate*64) / (1024 * 1024) - + // Calculate block utilization percentage blockUtilization := float64(receipt.GasUsed) / float64(blockGasLimit) * 100 diff --git a/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.go b/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.go deleted file mode 100644 index b99fb9f5..00000000 --- a/scenarios/statebloat/rand_sstore_bloater/contract/SSTOREStorageBloater.go +++ /dev/null @@ -1,225 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contract - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// ContractMetaData contains all meta data concerning the Contract contract. -var ContractMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"createSlots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052348015600e575f5ffd5b5060b780601a5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c8063e3b393a414602a575b5f5ffd5b60396035366004606b565b603b565b005b6013600160ff1b0381600143034042185f5b828110156064575f1984838301098055600101604d565b5050505050565b5f60208284031215607a575f5ffd5b503591905056fea26469706673582212204ef28faab84898d88945da94b05dca578974093de11f6a0be4b796396638d88264736f6c634300081e0033", -} - -// ContractABI is the input ABI used to generate the binding from. -// Deprecated: Use ContractMetaData.ABI instead. -var ContractABI = ContractMetaData.ABI - -// ContractBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ContractMetaData.Bin instead. -var ContractBin = ContractMetaData.Bin - -// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. -func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Contract, error) { - parsed, err := ContractMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// Contract is an auto generated Go binding around an Ethereum contract. -type Contract struct { - ContractCaller // Read-only binding to the contract - ContractTransactor // Write-only binding to the contract - ContractFilterer // Log filterer for contract events -} - -// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ContractCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ContractTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ContractFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// ContractSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ContractSession struct { - Contract *Contract // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ContractCallerSession struct { - Contract *ContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ContractTransactorSession struct { - Contract *ContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ContractRaw struct { - Contract *Contract // Generic contract binding to access the raw methods on -} - -// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ContractCallerRaw struct { - Contract *ContractCaller // Generic read-only contract binding to access the raw methods on -} - -// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ContractTransactorRaw struct { - Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewContract creates a new instance of Contract, bound to a specific deployed contract. -func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { - contract, err := bindContract(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil -} - -// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. -func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { - contract, err := bindContract(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ContractCaller{contract: contract}, nil -} - -// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. -func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { - contract, err := bindContract(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ContractTransactor{contract: contract}, nil -} - -// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. -func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { - contract, err := bindContract(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ContractFilterer{contract: contract}, nil -} - -// bindContract binds a generic wrapper to an already deployed contract. -func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := ContractMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.contract.Transact(opts, method, params...) -} - -// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. -// -// Solidity: function createSlots(uint256 count) returns() -func (_Contract *ContractTransactor) CreateSlots(opts *bind.TransactOpts, count *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "createSlots", count) -} - -// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. -// -// Solidity: function createSlots(uint256 count) returns() -func (_Contract *ContractSession) CreateSlots(count *big.Int) (*types.Transaction, error) { - return _Contract.Contract.CreateSlots(&_Contract.TransactOpts, count) -} - -// CreateSlots is a paid mutator transaction binding the contract method 0xe3b393a4. -// -// Solidity: function createSlots(uint256 count) returns() -func (_Contract *ContractTransactorSession) CreateSlots(count *big.Int) (*types.Transaction, error) { - return _Contract.Contract.CreateSlots(&_Contract.TransactOpts, count) -} - From 985ae2f3061896f82ba027b2eccc07b9c4287c65 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 14:09:32 +0200 Subject: [PATCH 29/39] small fixes for `statebloat-rand-sstore` --- .../rand_sstore/rand_sstore_bloater.go | 89 +++++++++++++------ spamoor/txpool.go | 25 ++++++ 2 files changed, 89 insertions(+), 25 deletions(-) diff --git a/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go index 7308d0b2..8df4e5ec 100644 --- a/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go +++ b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go @@ -24,6 +24,7 @@ import ( "github.com/ethpandaops/spamoor/scenarios/statebloat/rand_sstore/contract" "github.com/ethpandaops/spamoor/spamoor" "github.com/ethpandaops/spamoor/txbuilder" + "github.com/ethpandaops/spamoor/utils" ) // Constants for SSTORE operations @@ -374,36 +375,73 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo } // Create transaction options - auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), s.walletPool.GetChainId()) + feeCap, tipCap, err := s.walletPool.GetTxPool().GetSuggestedFees(client, s.options.BaseFee, s.options.TipFee) if err != nil { - return fmt.Errorf("failed to create transactor: %w", err) + return fmt.Errorf("failed to get suggested fees: %w", err) } - // Set gas parameters - auth.GasLimit = targetGas - auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) - auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) - - // Execute transaction using contract bindings - tx, err := s.contractInstance.CreateSlots(auth, big.NewInt(int64(slotsToCreate))) + tx, err := wallet.BuildBoundTx(ctx, &txbuilder.TxMetadata{ + GasFeeCap: uint256.MustFromBig(feeCap), + GasTipCap: uint256.MustFromBig(tipCap), + Gas: targetGas, + Value: uint256.NewInt(0), + }, func(transactOpts *bind.TransactOpts) (*types.Transaction, error) { + return s.contractInstance.CreateSlots(transactOpts, big.NewInt(int64(slotsToCreate))) + }) if err != nil { - // Check if it's an out-of-gas error - if strings.Contains(err.Error(), "out of gas") || strings.Contains(err.Error(), "OutOfGas") { - // Increase our gas estimate by 10% - s.actualGasPerNewSlotIteration = uint64(float64(s.actualGasPerNewSlotIteration) * 1.1) - s.logger.Warnf("Out of gas error detected. Adjusting gas per slot estimate to %d", s.actualGasPerNewSlotIteration) - } return err } - // Wait for transaction confirmation - receipt, err := bind.WaitMined(ctx, client.GetEthClient(), tx) + var txReceipt *types.Receipt + var txErr error + txWg := sync.WaitGroup{} + txWg.Add(1) + + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + Client: client, + Rebroadcast: true, + OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + txFees := utils.GetTransactionFees(tx, receipt) + s.logger.WithField("rpc", client.GetName()).Debugf(" transaction confirmed in block #%v. total fee: %v gwei (base: %v) logs: %v", receipt.BlockNumber.String(), txFees.TotalFeeGwei(), txFees.TxBaseFeeGwei(), len(receipt.Logs)) + txErr = err + txReceipt = receipt + txWg.Done() + }, + LogFn: func(client *spamoor.Client, retry int, rebroadcast int, err error) { + logger := s.logger.WithField("rpc", client.GetName()).WithField("nonce", tx.Nonce()) + if retry == 0 && rebroadcast > 0 { + logger.Infof("rebroadcasting tx") + } + if retry > 0 { + logger = logger.WithField("retry", retry) + } + if rebroadcast > 0 { + logger = logger.WithField("rebroadcast", rebroadcast) + } + if err != nil { + logger.Debugf("failed sending tx: %v", err) + } else if retry > 0 || rebroadcast > 0 { + logger.Debugf("successfully sent tx") + } + }, + }) if err != nil { - return fmt.Errorf("failed to wait for transaction: %w", err) + // reset nonce if tx was not sent + wallet.ResetPendingNonce(ctx, client) + + return err + } + + txWg.Wait() + if txErr != nil { + return fmt.Errorf("transaction failed: %w", txErr) } - if receipt.Status != 1 { - return fmt.Errorf("transaction failed") + if txReceipt == nil || txReceipt.Status != 1 { + // Increase our gas estimate by 10% + s.actualGasPerNewSlotIteration = uint64(float64(s.actualGasPerNewSlotIteration) * 1.1) + + return fmt.Errorf("transaction rejected") } // Mark this slot count as successful @@ -412,14 +450,15 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo // Update metrics and adaptive gas tracking s.totalSlots += slotsToCreate totalOverhead := BaseTxCost + FunctionCallOverhead - actualGasPerSlotIteration := (receipt.GasUsed - totalOverhead) / slotsToCreate + actualGasPerSlotIteration := (txReceipt.GasUsed - totalOverhead) / slotsToCreate // Update our gas estimate using exponential moving average // New estimate = 0.7 * old estimate + 0.3 * actual s.actualGasPerNewSlotIteration = uint64(float64(s.actualGasPerNewSlotIteration)*0.7 + float64(actualGasPerSlotIteration)*0.3) // Get previous block info for tracking - prevBlockNumber := receipt.BlockNumber.Uint64() - 1 + prevBlockNumber := txReceipt.BlockNumber.Uint64() - 1 + prevBlock, err := client.GetEthClient().BlockByNumber(ctx, big.NewInt(int64(prevBlockNumber))) if err != nil { s.logger.Warnf("failed to get previous block info: %v", err) @@ -448,11 +487,11 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo mbWrittenThisTx := float64(slotsToCreate*64) / (1024 * 1024) // Calculate block utilization percentage - blockUtilization := float64(receipt.GasUsed) / float64(blockGasLimit) * 100 + blockUtilization := float64(txReceipt.GasUsed) / float64(blockGasLimit) * 100 s.logger.WithFields(logrus.Fields{ - "block_number": receipt.BlockNumber, - "gas_used": receipt.GasUsed, + "block_number": txReceipt.BlockNumber, + "gas_used": txReceipt.GasUsed, "slots_created": slotsToCreate, "gas_per_slot": actualGasPerSlotIteration, "total_slots": s.totalSlots, diff --git a/spamoor/txpool.go b/spamoor/txpool.go index 4ae83220..b264f141 100644 --- a/spamoor/txpool.go +++ b/spamoor/txpool.go @@ -1071,6 +1071,31 @@ func (pool *TxPool) InitializeGasLimit() error { return nil } +func (pool *TxPool) GetSuggestedFees(client *Client, baseFeeGwei uint64, tipFeeGwei uint64) (feeCap *big.Int, tipCap *big.Int, err error) { + if baseFeeGwei > 0 { + feeCap = new(big.Int).Mul(big.NewInt(int64(baseFeeGwei)), big.NewInt(1000000000)) + } + if tipFeeGwei > 0 { + tipCap = new(big.Int).Mul(big.NewInt(int64(tipFeeGwei)), big.NewInt(1000000000)) + } + + if feeCap == nil || tipCap == nil { + feeCap, tipCap, err = client.GetSuggestedFee(pool.options.Context) + if err != nil { + return nil, nil, err + } + } + + if feeCap.Cmp(big.NewInt(1000000000)) < 0 { + feeCap = big.NewInt(1000000000) + } + if tipCap.Cmp(big.NewInt(1000000000)) < 0 { + tipCap = big.NewInt(1000000000) + } + + return feeCap, tipCap, nil +} + // calculateBackoffDelay calculates the exponential backoff delay for rebroadcast attempts. // Uses 30s base delay, 1.5x multiplier, with 10min maximum delay. func (pool *TxPool) calculateBackoffDelay(retryCount uint64) time.Duration { From 4b9eded138f47db34fb8029e52dad4484c9b26be Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 14:12:19 +0200 Subject: [PATCH 30/39] fix nil pointer panic --- scenarios/statebloat/rand_sstore/rand_sstore_bloater.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go index 8df4e5ec..15e68951 100644 --- a/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go +++ b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go @@ -401,8 +401,10 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo Client: client, Rebroadcast: true, OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { - txFees := utils.GetTransactionFees(tx, receipt) - s.logger.WithField("rpc", client.GetName()).Debugf(" transaction confirmed in block #%v. total fee: %v gwei (base: %v) logs: %v", receipt.BlockNumber.String(), txFees.TotalFeeGwei(), txFees.TxBaseFeeGwei(), len(receipt.Logs)) + if receipt != nil { + txFees := utils.GetTransactionFees(tx, receipt) + s.logger.WithField("rpc", client.GetName()).Debugf(" transaction confirmed in block #%v. total fee: %v gwei (base: %v) logs: %v", receipt.BlockNumber.String(), txFees.TotalFeeGwei(), txFees.TxBaseFeeGwei(), len(receipt.Logs)) + } txErr = err txReceipt = receipt txWg.Done() From a59fd695c11e3045b903ab89a27ceb98c3f23ac1 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 14:45:40 +0200 Subject: [PATCH 31/39] deduplicate gas calculation --- .../eoa_delegation/eoa_delegation.go | 54 +++---------------- .../rand_sstore/rand_sstore_bloater.go | 26 ++------- 2 files changed, 9 insertions(+), 71 deletions(-) diff --git a/scenarios/statebloat/eoa_delegation/eoa_delegation.go b/scenarios/statebloat/eoa_delegation/eoa_delegation.go index b4d16cc5..32d63f46 100644 --- a/scenarios/statebloat/eoa_delegation/eoa_delegation.go +++ b/scenarios/statebloat/eoa_delegation/eoa_delegation.go @@ -302,30 +302,9 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in } // Get suggested fees for funding transactions - var feeCap *big.Int - var tipCap *big.Int - - if s.options.BaseFee > 0 { - feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(GweiPerEth)) - } - if s.options.TipFee > 0 { - tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(GweiPerEth)) - } - - if feeCap == nil || tipCap == nil { - var err error - feeCap, tipCap, err = client.GetSuggestedFee(s.walletPool.GetContext()) - if err != nil { - return 0, fmt.Errorf("failed to get suggested fees for funding: %w", err) - } - } - - // Minimum gas prices - if feeCap.Cmp(big.NewInt(GweiPerEth)) < 0 { - feeCap = big.NewInt(GweiPerEth) - } - if tipCap.Cmp(big.NewInt(GweiPerEth)) < 0 { - tipCap = big.NewInt(GweiPerEth) + feeCap, tipCap, err := s.walletPool.GetTxPool().GetSuggestedFees(client, s.options.BaseFee, s.options.TipFee) + if err != nil { + return 0, fmt.Errorf("failed to get suggested fees for funding: %w", err) } // Fund with 1 wei as requested by user @@ -469,30 +448,9 @@ func (s *Scenario) sendMaxBloatingTransaction(ctx context.Context, targetAuthori } // Get suggested fees or use configured values - var feeCap *big.Int - var tipCap *big.Int - - if s.options.BaseFee > 0 { - feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(GweiPerEth)) - } - if s.options.TipFee > 0 { - tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(GweiPerEth)) - } - - if feeCap == nil || tipCap == nil { - var err error - feeCap, tipCap, err = client.GetSuggestedFee(s.walletPool.GetContext()) - if err != nil { - return 0, "", 0, 0, 0, "", fmt.Errorf("failed to get suggested fees: %w", err) - } - } - - // Ensure minimum gas prices for inclusion - if feeCap.Cmp(big.NewInt(GweiPerEth)) < 0 { - feeCap = big.NewInt(GweiPerEth) - } - if tipCap.Cmp(big.NewInt(GweiPerEth)) < 0 { - tipCap = big.NewInt(GweiPerEth) + feeCap, tipCap, err := s.walletPool.GetTxPool().GetSuggestedFees(client, s.options.BaseFee, s.options.TipFee) + if err != nil { + return 0, "", 0, 0, 0, "", fmt.Errorf("failed to get suggested fees for max bloating: %w", err) } // Use minimal amount for max bloating (focus on authorizations, not value transfer) diff --git a/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go index 15e68951..c58586a3 100644 --- a/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go +++ b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go @@ -214,29 +214,9 @@ func (s *Scenario) deployContract(ctx context.Context) error { return fmt.Errorf("no wallet available") } - var feeCap *big.Int - var tipCap *big.Int - - if s.options.BaseFee > 0 { - feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) - } - if s.options.TipFee > 0 { - tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) - } - - if feeCap == nil || tipCap == nil { - var err error - feeCap, tipCap, err = client.GetSuggestedFee(s.walletPool.GetContext()) - if err != nil { - return nil - } - } - - if feeCap.Cmp(big.NewInt(1000000000)) < 0 { - feeCap = big.NewInt(1000000000) - } - if tipCap.Cmp(big.NewInt(1000000000)) < 0 { - tipCap = big.NewInt(1000000000) + feeCap, tipCap, err := s.walletPool.GetTxPool().GetSuggestedFees(client, s.options.BaseFee, s.options.TipFee) + if err != nil { + return err } tx, err := wallet.BuildBoundTx(ctx, &txbuilder.TxMetadata{ From a95cfe1f3ae9db0969e073c131f9d14e4266f7ea Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 16:18:02 +0200 Subject: [PATCH 32/39] streamline `statebloat-contract-deploy` scenario --- .../contract_deploy/contract/.gitignore | 3 + .../contract/StateBloatToken.abi | 1 - .../contract/StateBloatToken.bin | 1 - .../contract/StateBloatToken.go | 1517 +++++++++-------- .../contract_deploy/contract/compile.sh | 35 + .../contract_deploy/contract_deploy.go | 388 ++--- 6 files changed, 969 insertions(+), 976 deletions(-) create mode 100644 scenarios/statebloat/contract_deploy/contract/.gitignore delete mode 100644 scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi delete mode 100644 scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin create mode 100755 scenarios/statebloat/contract_deploy/contract/compile.sh diff --git a/scenarios/statebloat/contract_deploy/contract/.gitignore b/scenarios/statebloat/contract_deploy/contract/.gitignore new file mode 100644 index 00000000..f9096e53 --- /dev/null +++ b/scenarios/statebloat/contract_deploy/contract/.gitignore @@ -0,0 +1,3 @@ +*.output.json +*.bin +*.abi \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi deleted file mode 100644 index 0f67a8f3..00000000 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.abi +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"uint256","name":"_salt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dummy1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy10","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy11","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy12","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy13","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy14","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy15","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy16","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy17","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy19","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy21","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy22","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy23","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy24","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy25","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy26","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy27","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy28","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy29","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy30","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy31","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy32","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy33","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy34","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy35","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy36","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy37","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy38","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy39","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy4","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy40","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy41","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy42","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy43","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy44","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy45","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy46","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy47","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy48","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy49","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy5","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy50","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy51","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy52","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy53","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy54","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy55","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy56","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy57","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy58","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy59","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy6","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy60","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy61","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy62","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy63","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy64","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy65","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy7","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy8","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dummy9","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom1","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom10","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom11","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom12","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom13","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom14","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom15","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom16","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom17","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom18","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom19","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom2","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom3","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom4","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom5","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom6","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom7","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom8","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom9","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin deleted file mode 100644 index 755497f1..00000000 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.bin +++ /dev/null @@ -1 +0,0 @@ -60a060405234801561000f575f5ffd5b50604051615fba380380615fba833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b6080516158656107555f395f61493601526158655ff3fe608060405234801561000f575f5ffd5b506004361061057f575f3560e01c8063657b6ef7116102e3578063ad8f42211161018b578063d9bb3174116100f2578063ee1682b6116100ab578063f8716f1411610085578063f8716f1414611243578063faf35ced14611261578063fe7d599614611291578063ffbf0469146112af5761057f565b8063ee1682b6146111e9578063f26c779b14611207578063f5f57381146112255761057f565b8063d9bb317414611111578063dc1d8a9b1461112f578063dd62ed3e1461114d578063e2d275301461117d578063e8c927b31461119b578063eb4329c8146111b95761057f565b8063bfa0b13311610144578063bfa0b1331461104b578063c2be97e314611069578063c958d4bf14611099578063cfd66863146110b7578063d101dcd0146110d5578063d7419469146110f35761057f565b8063ad8f422114610f73578063b1802b9a14610f91578063b2bb360e14610fc1578063b66dd75014610fdf578063b9a6d64514610ffd578063bb9bfe061461101b5761057f565b80637dffdc321161024a57806395d89b4111610203578063a891d4d4116101dd578063a891d4d414610ed7578063a9059cbb14610ef5578063aaa7af7014610f25578063acc5aee914610f435761057f565b806395d89b4114610e7d5780639c5dfe7314610e9b5780639df61a2514610eb95761057f565b80637dffdc3214610db75780637e54493714610dd55780637f34d94b14610df35780638619d60714610e115780638789ca6714610e2f5780638f4a840614610e5f5761057f565b806374f83d021161029c57806374f83d0214610cf157806377c0209e14610d0f578063792c7f3e14610d2d5780637a319c1814610d4b5780637c66673e14610d695780637c72ed0d14610d995761057f565b8063657b6ef714610c07578063672151fe14610c375780636abceacd14610c555780636c12ed2814610c7357806370a0823114610ca357806374e73fd314610cd35761057f565b80633125f37a116104465780634a2e93c6116103ad578063552a1b561161036657806361b970eb1161034057806361b970eb14610b8f578063639ec53a14610bad5780636547317414610bcb5780636578534c14610be95761057f565b8063552a1b5614610b2357806358b6a9bd14610b535780635af92c0514610b715761057f565b80634a2e93c614610a5d5780634b3c7f5f14610a7b5780634e1dbb8214610a995780634f5e555714610ab75780634f7bd75a14610ad557806354c2792014610b055761057f565b80633ea117ce116103ff5780633ea117ce146109975780634128a85d146109b5578063418b1816146109d357806342937dbd146109f157806343a6b92d14610a0f57806344050a2814610a2d5761057f565b80633125f37a146108bf578063313ce567146108dd57806334517f0b146108fb57806339e0bd12146109195780633a131990146109495780633b6be459146109795761057f565b80631b17c65c116104ea57806321ecd7a3116104a357806321ecd7a3146107e7578063239af2a51461080557806323b872dd146108235780632545d8b7146108535780632787325b14610871578063291c3bd71461088f5761057f565b80631b17c65c1461070f5780631bbffe6f1461073f5780631d527cde1461076f5780631eaa7c521461078d5780631f449589146107ab5780631fd298ec146107c95761057f565b806312901b421161053c57806312901b421461065b57806313ebb5ec1461067957806316a3045b1461069757806318160ddd146106b557806319cf6a91146106d35780631a97f18e146106f15761057f565b80630460faf61461058357806306fdde03146105b35780630717b161146105d1578063095ea7b3146105ef5780630cb7a9e71461061f5780631215a3ab1461063d575b5f5ffd5b61059d60048036038101906105989190615275565b6112cd565b6040516105aa91906152df565b60405180910390f35b6105bb6115ad565b6040516105c89190615368565b60405180910390f35b6105d9611638565b6040516105e69190615397565b60405180910390f35b610609600480360381019061060491906153b0565b611640565b60405161061691906152df565b60405180910390f35b61062761172d565b6040516106349190615397565b60405180910390f35b610645611735565b6040516106529190615397565b60405180910390f35b61066361173d565b6040516106709190615397565b60405180910390f35b610681611745565b60405161068e9190615397565b60405180910390f35b61069f61174d565b6040516106ac9190615397565b60405180910390f35b6106bd611755565b6040516106ca9190615397565b60405180910390f35b6106db61175b565b6040516106e89190615397565b60405180910390f35b6106f9611763565b6040516107069190615397565b60405180910390f35b61072960048036038101906107249190615275565b61176b565b60405161073691906152df565b60405180910390f35b61075960048036038101906107549190615275565b611a4b565b60405161076691906152df565b60405180910390f35b610777611d2b565b6040516107849190615397565b60405180910390f35b610795611d33565b6040516107a29190615397565b60405180910390f35b6107b3611d3b565b6040516107c09190615397565b60405180910390f35b6107d1611d43565b6040516107de9190615397565b60405180910390f35b6107ef611d4b565b6040516107fc9190615397565b60405180910390f35b61080d611d53565b60405161081a9190615397565b60405180910390f35b61083d60048036038101906108389190615275565b611d5b565b60405161084a91906152df565b60405180910390f35b61085b61203b565b6040516108689190615397565b60405180910390f35b610879612043565b6040516108869190615397565b60405180910390f35b6108a960048036038101906108a49190615275565b61204b565b6040516108b691906152df565b60405180910390f35b6108c761232b565b6040516108d49190615397565b60405180910390f35b6108e5612333565b6040516108f29190615409565b60405180910390f35b610903612345565b6040516109109190615397565b60405180910390f35b610933600480360381019061092e9190615275565b61234d565b60405161094091906152df565b60405180910390f35b610963600480360381019061095e9190615275565b61262d565b60405161097091906152df565b60405180910390f35b61098161290d565b60405161098e9190615397565b60405180910390f35b61099f612915565b6040516109ac9190615397565b60405180910390f35b6109bd61291d565b6040516109ca9190615397565b60405180910390f35b6109db612925565b6040516109e89190615397565b60405180910390f35b6109f961292d565b604051610a069190615397565b60405180910390f35b610a17612935565b604051610a249190615397565b60405180910390f35b610a476004803603810190610a429190615275565b61293d565b604051610a5491906152df565b60405180910390f35b610a65612c1d565b604051610a729190615397565b60405180910390f35b610a83612c25565b604051610a909190615397565b60405180910390f35b610aa1612c2d565b604051610aae9190615397565b60405180910390f35b610abf612c35565b604051610acc9190615397565b60405180910390f35b610aef6004803603810190610aea9190615275565b612c3d565b604051610afc91906152df565b60405180910390f35b610b0d612f1d565b604051610b1a9190615397565b60405180910390f35b610b3d6004803603810190610b389190615275565b612f25565b604051610b4a91906152df565b60405180910390f35b610b5b613205565b604051610b689190615397565b60405180910390f35b610b7961320d565b604051610b869190615397565b60405180910390f35b610b97613215565b604051610ba49190615397565b60405180910390f35b610bb561321d565b604051610bc29190615397565b60405180910390f35b610bd3613225565b604051610be09190615397565b60405180910390f35b610bf161322d565b604051610bfe9190615397565b60405180910390f35b610c216004803603810190610c1c9190615275565b613235565b604051610c2e91906152df565b60405180910390f35b610c3f613515565b604051610c4c9190615397565b60405180910390f35b610c5d61351d565b604051610c6a9190615397565b60405180910390f35b610c8d6004803603810190610c889190615275565b613525565b604051610c9a91906152df565b60405180910390f35b610cbd6004803603810190610cb89190615422565b613805565b604051610cca9190615397565b60405180910390f35b610cdb61381a565b604051610ce89190615397565b60405180910390f35b610cf9613822565b604051610d069190615397565b60405180910390f35b610d1761382a565b604051610d249190615397565b60405180910390f35b610d35613832565b604051610d429190615397565b60405180910390f35b610d5361383a565b604051610d609190615397565b60405180910390f35b610d836004803603810190610d7e9190615275565b613842565b604051610d9091906152df565b60405180910390f35b610da1613b22565b604051610dae9190615397565b60405180910390f35b610dbf613b2a565b604051610dcc9190615397565b60405180910390f35b610ddd613b32565b604051610dea9190615397565b60405180910390f35b610dfb613b3a565b604051610e089190615397565b60405180910390f35b610e19613b42565b604051610e269190615397565b60405180910390f35b610e496004803603810190610e449190615275565b613b4a565b604051610e5691906152df565b60405180910390f35b610e67613e2a565b604051610e749190615397565b60405180910390f35b610e85613e32565b604051610e929190615368565b60405180910390f35b610ea3613ebe565b604051610eb09190615397565b60405180910390f35b610ec1613ec6565b604051610ece9190615397565b60405180910390f35b610edf613ece565b604051610eec9190615397565b60405180910390f35b610f0f6004803603810190610f0a91906153b0565b613ed6565b604051610f1c91906152df565b60405180910390f35b610f2d61406c565b604051610f3a9190615397565b60405180910390f35b610f5d6004803603810190610f589190615275565b614074565b604051610f6a91906152df565b60405180910390f35b610f7b614354565b604051610f889190615397565b60405180910390f35b610fab6004803603810190610fa69190615275565b61435c565b604051610fb891906152df565b60405180910390f35b610fc961463c565b604051610fd69190615397565b60405180910390f35b610fe7614644565b604051610ff49190615397565b60405180910390f35b61100561464c565b6040516110129190615397565b60405180910390f35b61103560048036038101906110309190615275565b614654565b60405161104291906152df565b60405180910390f35b611053614934565b6040516110609190615397565b60405180910390f35b611083600480360381019061107e9190615275565b614958565b60405161109091906152df565b60405180910390f35b6110a1614c38565b6040516110ae9190615397565b60405180910390f35b6110bf614c40565b6040516110cc9190615397565b60405180910390f35b6110dd614c48565b6040516110ea9190615397565b60405180910390f35b6110fb614c50565b6040516111089190615397565b60405180910390f35b611119614c58565b6040516111269190615397565b60405180910390f35b611137614c60565b6040516111449190615397565b60405180910390f35b6111676004803603810190611162919061544d565b614c68565b6040516111749190615397565b60405180910390f35b611185614c88565b6040516111929190615397565b60405180910390f35b6111a3614c90565b6040516111b09190615397565b60405180910390f35b6111d360048036038101906111ce9190615275565b614c98565b6040516111e091906152df565b60405180910390f35b6111f1614ebd565b6040516111fe9190615368565b60405180910390f35b61120f614edc565b60405161121c9190615397565b60405180910390f35b61122d614ee4565b60405161123a9190615397565b60405180910390f35b61124b614eec565b6040516112589190615397565b60405180910390f35b61127b60048036038101906112769190615275565b614ef4565b60405161128891906152df565b60405180910390f35b6112996151d4565b6040516112a69190615397565b60405180910390f35b6112b76151dc565b6040516112c49190615397565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561134e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611345906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611409576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114009061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546114559190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546114a891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546115369190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161159a9190615397565b60405180910390a3600190509392505050565b5f80546115b99061561b565b80601f01602080910402602001604051908101604052809291908181526020018280546115e59061561b565b80156116305780601f1061160757610100808354040283529160200191611630565b820191905f5260205f20905b81548152906001019060200180831161161357829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161171b9190615397565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156117ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117e3906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156118a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189e9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546118f39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461194691906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546119d49190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611a389190615397565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611acc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac3906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611b87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7e9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611bd39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611c2691906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611cb49190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611d189190615397565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611ddc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd3906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611e97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e8e9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ee39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611f3691906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611fc49190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516120289190615397565b60405180910390a3600190509392505050565b5f6001905090565b5f6045905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156120cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c390615695565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217e906156fd565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546121d39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461222691906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546122b49190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516123189190615397565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156123ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c5906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612489576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124809061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546124d59190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461252891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546125b69190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161261a9190615397565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156126ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a5906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612769576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127609061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546127b59190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461280891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546128969190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516128fa9190615397565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156129be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b5906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612a79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a709061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ac59190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612b1891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ba69190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612c0a9190615397565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612cbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cb5906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612d79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d709061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612dc59190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612e1891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ea69190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612f0a9190615397565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612fa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f9d906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613061576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130589061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546130ad9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461310091906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461318e9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131f29190615397565b60405180910390a3600190509392505050565b5f6009905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f6043905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156132b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ad90615695565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613368906156fd565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546133bd9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461341091906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461349e9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516135029190615397565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156135a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161359d906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613661576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136589061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546136ad9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461370091906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461378e9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516137f29190615397565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156138c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138ba906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561397e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139759061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546139ca9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613a1d91906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613aab9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613b0f9190615397565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613bcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613bc2906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c7d9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613cd29190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613d2591906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613db39190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613e179190615397565b60405180910390a3600190509392505050565b5f600b905090565b60018054613e3f9061561b565b80601f0160208091040260200160405190810160405280929190818152602001828054613e6b9061561b565b8015613eb65780601f10613e8d57610100808354040283529160200191613eb6565b820191905f5260205f20905b815481529060010190602001808311613e9957829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613f57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613f4e906154d5565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613fa39190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ff691906155bb565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161405a9190615397565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156140f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016140ec906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156141b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016141a79061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546141fc9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461424f91906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546142dd9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516143419190615397565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156143dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016143d4906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161448f9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546144e49190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461453791906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546145c59190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516146299190615397565b60405180910390a3600190509392505050565b5f6018905090565b5f600f905090565b5f6044905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156146d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016146cc906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614790576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016147879061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546147dc9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461482f91906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546148bd9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516149219190615397565b60405180910390a3600190509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156149d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016149d0906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614a94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614a8b9061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614ae09190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614b3391906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614bc19190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614c259190615397565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6042905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614d19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614d1090615695565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d659190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614db891906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614e469190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614eaa9190615397565b60405180910390a3600190509392505050565b604051806101400160405280610114815260200161571c610114913981565b5f6007905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614f75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614f6c906154d5565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015615030576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016150279061553d565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461507c9190615588565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546150cf91906155bb565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461515d9190615588565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516151c19190615397565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f615211826151e8565b9050919050565b61522181615207565b811461522b575f5ffd5b50565b5f8135905061523c81615218565b92915050565b5f819050919050565b61525481615242565b811461525e575f5ffd5b50565b5f8135905061526f8161524b565b92915050565b5f5f5f6060848603121561528c5761528b6151e4565b5b5f6152998682870161522e565b93505060206152aa8682870161522e565b92505060406152bb86828701615261565b9150509250925092565b5f8115159050919050565b6152d9816152c5565b82525050565b5f6020820190506152f25f8301846152d0565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61533a826152f8565b6153448185615302565b9350615354818560208601615312565b61535d81615320565b840191505092915050565b5f6020820190508181035f8301526153808184615330565b905092915050565b61539181615242565b82525050565b5f6020820190506153aa5f830184615388565b92915050565b5f5f604083850312156153c6576153c56151e4565b5b5f6153d38582860161522e565b92505060206153e485828601615261565b9150509250929050565b5f60ff82169050919050565b615403816153ee565b82525050565b5f60208201905061541c5f8301846153fa565b92915050565b5f60208284031215615437576154366151e4565b5b5f6154448482850161522e565b91505092915050565b5f5f60408385031215615463576154626151e4565b5b5f6154708582860161522e565b92505060206154818582860161522e565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6154bf601483615302565b91506154ca8261548b565b602082019050919050565b5f6020820190508181035f8301526154ec816154b3565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f615527601683615302565b9150615532826154f3565b602082019050919050565b5f6020820190508181035f8301526155548161551b565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61559282615242565b915061559d83615242565b92508282039050818111156155b5576155b461555b565b5b92915050565b5f6155c582615242565b91506155d083615242565b92508282019050808211156155e8576155e761555b565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061563257607f821691505b602082108103615645576156446155ee565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f61567f600183615302565b915061568a8261564b565b602082019050919050565b5f6020820190508181035f8301526156ac81615673565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6156e7600183615302565b91506156f2826156b3565b602082019050919050565b5f6020820190508181035f830152615714816156db565b905091905056fe414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141a26469706673582212203e477b8749988ccd0a67b1a6d43c11976c00a420dbe43a9f84158e8962430d7664736f6c634300081e0033 \ No newline at end of file diff --git a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go index 13a8ab62..3021968a 100644 --- a/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go +++ b/scenarios/statebloat/contract_deploy/contract/StateBloatToken.go @@ -29,23 +29,23 @@ var ( _ = abi.ConvertType ) -// ContractMetaData contains all meta data concerning the Contract contract. -var ContractMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy10\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy11\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy12\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy13\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy14\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy15\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy16\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy17\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy18\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy19\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy2\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy20\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy21\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy22\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy23\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy24\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy25\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy26\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy27\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy28\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy29\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy3\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy30\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy31\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy32\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy33\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy34\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy35\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy36\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy37\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy38\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy39\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy4\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy40\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy41\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy42\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy43\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy44\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy45\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy46\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy47\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy48\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy49\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy5\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy50\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy51\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy52\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy53\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy54\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy55\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy56\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy57\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy58\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy59\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy6\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy60\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy61\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy62\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy63\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy64\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy65\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy7\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy8\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy9\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"salt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom1\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom10\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom11\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom12\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom13\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom14\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom15\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom16\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom17\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom18\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom19\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom3\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom4\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom5\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom6\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom7\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom8\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom9\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561000f575f5ffd5b50604051615d6a380380615d6a833981810160405281019061003191906101f4565b6040518060400160405280601181526020017f537461746520426c6f617420546f6b656e0000000000000000000000000000008152505f90816100749190610453565b506040518060400160405280600381526020017f5342540000000000000000000000000000000000000000000000000000000000815250600190816100b99190610453565b50601260025f6101000a81548160ff021916908360ff160217905550806080818152505060025f9054906101000a900460ff16600a6100f8919061068a565b620f424061010691906106d4565b60038190555060035460045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055503373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6003546040516101af9190610724565b60405180910390a35061073d565b5f5ffd5b5f819050919050565b6101d3816101c1565b81146101dd575f5ffd5b50565b5f815190506101ee816101ca565b92915050565b5f60208284031215610209576102086101bd565b5b5f610216848285016101e0565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061029a57607f821691505b6020821081036102ad576102ac610256565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261030f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102d4565b61031986836102d4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61035461034f61034a846101c1565b610331565b6101c1565b9050919050565b5f819050919050565b61036d8361033a565b6103816103798261035b565b8484546102e0565b825550505050565b5f5f905090565b610398610389565b6103a3818484610364565b505050565b5b818110156103c6576103bb5f82610390565b6001810190506103a9565b5050565b601f82111561040b576103dc816102b3565b6103e5846102c5565b810160208510156103f4578190505b610408610400856102c5565b8301826103a8565b50505b505050565b5f82821c905092915050565b5f61042b5f1984600802610410565b1980831691505092915050565b5f610443838361041c565b9150826002028217905092915050565b61045c8261021f565b67ffffffffffffffff81111561047557610474610229565b5b61047f8254610283565b61048a8282856103ca565b5f60209050601f8311600181146104bb575f84156104a9578287015190505b6104b38582610438565b86555061051a565b601f1984166104c9866102b3565b5f5b828110156104f0578489015182556001820191506020850194506020810190506104cb565b8683101561050d5784890151610509601f89168261041c565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b60018511156105a4578086048111156105805761057f610522565b5b600185161561058f5780820291505b808102905061059d8561054f565b9450610564565b94509492505050565b5f826105bc5760019050610677565b816105c9575f9050610677565b81600181146105df57600281146105e957610618565b6001915050610677565b60ff8411156105fb576105fa610522565b5b8360020a91508482111561061257610611610522565b5b50610677565b5060208310610133831016604e8410600b841016171561064d5782820a90508381111561064857610647610522565b5b610677565b61065a848484600161055b565b9250905081840481111561067157610670610522565b5b81810290505b9392505050565b5f60ff82169050919050565b5f610694826101c1565b915061069f8361067e565b92506106cc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846105ad565b905092915050565b5f6106de826101c1565b91506106e9836101c1565b92508282026106f7816101c1565b9150828204841483151761070e5761070d610522565b5b5092915050565b61071e816101c1565b82525050565b5f6020820190506107375f830184610715565b92915050565b6080516156156107555f395f61482101526156155ff3fe608060405234801561000f575f5ffd5b5060043610610518575f3560e01c8063657b6ef7116102a2578063aaa7af7011610170578063d7419469116100d7578063f26c779b11610090578063f26c779b1461110a578063f5f5738114611128578063f8716f1414611146578063faf35ced14611164578063fe7d599614611194578063ffbf0469146111b257610518565b8063d741946914611032578063dc1d8a9b14611050578063dd62ed3e1461106e578063e2d275301461109e578063e8c927b3146110bc578063eb4329c8146110da57610518565b8063bb9bfe0611610129578063bb9bfe0614610f5a578063bfa0b13314610f8a578063c2be97e314610fa8578063c958d4bf14610fd8578063cfd6686314610ff6578063d101dcd01461101457610518565b8063aaa7af7014610e82578063acc5aee914610ea0578063ad8f422114610ed0578063b1802b9a14610eee578063b2bb360e14610f1e578063b66dd75014610f3c57610518565b80637c72ed0d116102145780638f4a8406116101cd5780638f4a840614610dbc57806395d89b4114610dda5780639c5dfe7314610df85780639df61a2514610e16578063a891d4d414610e34578063a9059cbb14610e5257610518565b80637c72ed0d14610cf65780637dffdc3214610d145780637e54493714610d325780637f34d94b14610d505780638619d60714610d6e5780638789ca6714610d8c57610518565b806374e73fd31161026657806374e73fd314610c3057806374f83d0214610c4e57806377c0209e14610c6c578063792c7f3e14610c8a5780637a319c1814610ca85780637c66673e14610cc657610518565b8063657b6ef714610b64578063672151fe14610b945780636abceacd14610bb25780636c12ed2814610bd057806370a0823114610c0057610518565b80633125f37a116103ea5780634a2e93c611610351578063552a1b561161030a578063552a1b5614610a9e57806358b6a9bd14610ace5780635af92c0514610aec57806361b970eb14610b0a578063639ec53a14610b285780636547317414610b4657610518565b80634a2e93c6146109d85780634b3c7f5f146109f65780634e1dbb8214610a145780634f5e555714610a325780634f7bd75a14610a5057806354c2792014610a8057610518565b80633ea117ce116103a35780633ea117ce146109125780634128a85d14610930578063418b18161461094e57806342937dbd1461096c57806343a6b92d1461098a57806344050a28146109a857610518565b80633125f37a1461083a578063313ce5671461085857806334517f0b1461087657806339e0bd12146108945780633a131990146108c45780633b6be459146108f457610518565b80631a97f18e1161048e5780631fd298ec116104475780631fd298ec1461076257806321ecd7a314610780578063239af2a51461079e57806323b872dd146107bc5780632545d8b7146107ec578063291c3bd71461080a57610518565b80631a97f18e1461068a5780631b17c65c146106a85780631bbffe6f146106d85780631d527cde146107085780631eaa7c52146107265780631f4495891461074457610518565b80631215a3ab116104e05780631215a3ab146105d657806312901b42146105f457806313ebb5ec1461061257806316a3045b1461063057806318160ddd1461064e57806319cf6a911461066c57610518565b80630460faf61461051c57806306fdde031461054c5780630717b1611461056a578063095ea7b3146105885780630cb7a9e7146105b8575b5f5ffd5b61053660048036038101906105319190615139565b6111d0565b60405161054391906151a3565b60405180910390f35b6105546114b0565b604051610561919061522c565b60405180910390f35b61057261153b565b60405161057f919061525b565b60405180910390f35b6105a2600480360381019061059d9190615274565b611543565b6040516105af91906151a3565b60405180910390f35b6105c0611630565b6040516105cd919061525b565b60405180910390f35b6105de611638565b6040516105eb919061525b565b60405180910390f35b6105fc611640565b604051610609919061525b565b60405180910390f35b61061a611648565b604051610627919061525b565b60405180910390f35b610638611650565b604051610645919061525b565b60405180910390f35b610656611658565b604051610663919061525b565b60405180910390f35b61067461165e565b604051610681919061525b565b60405180910390f35b610692611666565b60405161069f919061525b565b60405180910390f35b6106c260048036038101906106bd9190615139565b61166e565b6040516106cf91906151a3565b60405180910390f35b6106f260048036038101906106ed9190615139565b61194e565b6040516106ff91906151a3565b60405180910390f35b610710611c2e565b60405161071d919061525b565b60405180910390f35b61072e611c36565b60405161073b919061525b565b60405180910390f35b61074c611c3e565b604051610759919061525b565b60405180910390f35b61076a611c46565b604051610777919061525b565b60405180910390f35b610788611c4e565b604051610795919061525b565b60405180910390f35b6107a6611c56565b6040516107b3919061525b565b60405180910390f35b6107d660048036038101906107d19190615139565b611c5e565b6040516107e391906151a3565b60405180910390f35b6107f4611f3e565b604051610801919061525b565b60405180910390f35b610824600480360381019061081f9190615139565b611f46565b60405161083191906151a3565b60405180910390f35b610842612226565b60405161084f919061525b565b60405180910390f35b61086061222e565b60405161086d91906152cd565b60405180910390f35b61087e612240565b60405161088b919061525b565b60405180910390f35b6108ae60048036038101906108a99190615139565b612248565b6040516108bb91906151a3565b60405180910390f35b6108de60048036038101906108d99190615139565b612528565b6040516108eb91906151a3565b60405180910390f35b6108fc612808565b604051610909919061525b565b60405180910390f35b61091a612810565b604051610927919061525b565b60405180910390f35b610938612818565b604051610945919061525b565b60405180910390f35b610956612820565b604051610963919061525b565b60405180910390f35b610974612828565b604051610981919061525b565b60405180910390f35b610992612830565b60405161099f919061525b565b60405180910390f35b6109c260048036038101906109bd9190615139565b612838565b6040516109cf91906151a3565b60405180910390f35b6109e0612b18565b6040516109ed919061525b565b60405180910390f35b6109fe612b20565b604051610a0b919061525b565b60405180910390f35b610a1c612b28565b604051610a29919061525b565b60405180910390f35b610a3a612b30565b604051610a47919061525b565b60405180910390f35b610a6a6004803603810190610a659190615139565b612b38565b604051610a7791906151a3565b60405180910390f35b610a88612e18565b604051610a95919061525b565b60405180910390f35b610ab86004803603810190610ab39190615139565b612e20565b604051610ac591906151a3565b60405180910390f35b610ad6613100565b604051610ae3919061525b565b60405180910390f35b610af4613108565b604051610b01919061525b565b60405180910390f35b610b12613110565b604051610b1f919061525b565b60405180910390f35b610b30613118565b604051610b3d919061525b565b60405180910390f35b610b4e613120565b604051610b5b919061525b565b60405180910390f35b610b7e6004803603810190610b799190615139565b613128565b604051610b8b91906151a3565b60405180910390f35b610b9c613408565b604051610ba9919061525b565b60405180910390f35b610bba613410565b604051610bc7919061525b565b60405180910390f35b610bea6004803603810190610be59190615139565b613418565b604051610bf791906151a3565b60405180910390f35b610c1a6004803603810190610c1591906152e6565b6136f8565b604051610c27919061525b565b60405180910390f35b610c3861370d565b604051610c45919061525b565b60405180910390f35b610c56613715565b604051610c63919061525b565b60405180910390f35b610c7461371d565b604051610c81919061525b565b60405180910390f35b610c92613725565b604051610c9f919061525b565b60405180910390f35b610cb061372d565b604051610cbd919061525b565b60405180910390f35b610ce06004803603810190610cdb9190615139565b613735565b604051610ced91906151a3565b60405180910390f35b610cfe613a15565b604051610d0b919061525b565b60405180910390f35b610d1c613a1d565b604051610d29919061525b565b60405180910390f35b610d3a613a25565b604051610d47919061525b565b60405180910390f35b610d58613a2d565b604051610d65919061525b565b60405180910390f35b610d76613a35565b604051610d83919061525b565b60405180910390f35b610da66004803603810190610da19190615139565b613a3d565b604051610db391906151a3565b60405180910390f35b610dc4613d1d565b604051610dd1919061525b565b60405180910390f35b610de2613d25565b604051610def919061522c565b60405180910390f35b610e00613db1565b604051610e0d919061525b565b60405180910390f35b610e1e613db9565b604051610e2b919061525b565b60405180910390f35b610e3c613dc1565b604051610e49919061525b565b60405180910390f35b610e6c6004803603810190610e679190615274565b613dc9565b604051610e7991906151a3565b60405180910390f35b610e8a613f5f565b604051610e97919061525b565b60405180910390f35b610eba6004803603810190610eb59190615139565b613f67565b604051610ec791906151a3565b60405180910390f35b610ed8614247565b604051610ee5919061525b565b60405180910390f35b610f086004803603810190610f039190615139565b61424f565b604051610f1591906151a3565b60405180910390f35b610f2661452f565b604051610f33919061525b565b60405180910390f35b610f44614537565b604051610f51919061525b565b60405180910390f35b610f746004803603810190610f6f9190615139565b61453f565b604051610f8191906151a3565b60405180910390f35b610f9261481f565b604051610f9f919061525b565b60405180910390f35b610fc26004803603810190610fbd9190615139565b614843565b604051610fcf91906151a3565b60405180910390f35b610fe0614b23565b604051610fed919061525b565b60405180910390f35b610ffe614b2b565b60405161100b919061525b565b60405180910390f35b61101c614b33565b604051611029919061525b565b60405180910390f35b61103a614b3b565b604051611047919061525b565b60405180910390f35b611058614b43565b604051611065919061525b565b60405180910390f35b61108860048036038101906110839190615311565b614b4b565b604051611095919061525b565b60405180910390f35b6110a6614b6b565b6040516110b3919061525b565b60405180910390f35b6110c4614b73565b6040516110d1919061525b565b60405180910390f35b6110f460048036038101906110ef9190615139565b614b7b565b60405161110191906151a3565b60405180910390f35b611112614da0565b60405161111f919061525b565b60405180910390f35b611130614da8565b60405161113d919061525b565b60405180910390f35b61114e614db0565b60405161115b919061525b565b60405180910390f35b61117e60048036038101906111799190615139565b614db8565b60405161118b91906151a3565b60405180910390f35b61119c615098565b6040516111a9919061525b565b60405180910390f35b6111ba6150a0565b6040516111c7919061525b565b60405180910390f35b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124890615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561130c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130390615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611358919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546113ab919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611439919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161149d919061525b565b60405180910390a3600190509392505050565b5f80546114bc906154df565b80601f01602080910402602001604051908101604052809291908181526020018280546114e8906154df565b80156115335780601f1061150a57610100808354040283529160200191611533565b820191905f5260205f20905b81548152906001019060200180831161151657829003601f168201915b505050505081565b5f602f905090565b5f8160055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161161e919061525b565b60405180910390a36001905092915050565b5f601b905090565b5f6005905090565b5f601a905090565b5f601d905090565b5f6033905090565b60035481565b5f6008905090565b5f6003905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156116ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156117aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546117f6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611849919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546118d7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161193b919061525b565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156119cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611a8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ad6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611b29919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611bb7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c1b919061525b565b60405180910390a3600190509392505050565b5f6002905090565b5f6010905090565b5f6041905090565b5f6035905090565b5f602e905090565b5f602c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd690615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611d9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9190615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611de6919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611e39919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611ec7919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611f2b919061525b565b60405180910390a3600190509392505050565b5f6001905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015611fc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fbe90615559565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612082576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612079906155c1565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546120ce919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612121919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546121af919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612213919061525b565b60405180910390a3600190509392505050565b5f6034905090565b60025f9054906101000a900460ff1681565b5f603c905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156122c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546123d0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612423919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546124b1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612515919061525b565b60405180910390a3600190509392505050565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156125a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125a090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546126b0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612703919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612791919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516127f5919061525b565b60405180910390a3600190509392505050565b5f6004905090565b5f600c905090565b5f6006905090565b5f601c905090565b5f6032905090565b5f6023905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156128b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161296b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546129c0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612a13919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612aa1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b05919061525b565b60405180910390a3600190509392505050565b5f6011905090565b5f6021905090565b5f601f905090565b5f6026905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612bb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c6b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612cc0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612d13919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612da1919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612e05919061525b565b60405180910390a3600190509392505050565b5f603a905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612ea1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9890615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015612f5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5390615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612fa8919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612ffb919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613089919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130ed919061525b565b60405180910390a3600190509392505050565b5f6009905090565b5f602a905090565b5f6014905090565b5f6025905090565b5f6013905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156131a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a090615559565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161325b906155c1565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546132b0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613303919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613391919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516133f5919061525b565b60405180910390a3600190509392505050565b5f600d905090565b5f6017905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613499576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161349090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161354b90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135a0919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546135f3919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613681919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516136e5919061525b565b60405180910390a3600190509392505050565b6004602052805f5260405f205f915090505481565b5f6016905090565b5f6039905090565b5f603b905090565b5f6036905090565b5f603f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156137b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137ad90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161386890615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546138bd919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613910919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461399e919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613a02919061525b565b60405180910390a3600190509392505050565b5f602b905090565b5f6037905090565b5f600a905090565b5f602d905090565b5f6030905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613abe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ab590615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613b79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b7090615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613bc5919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613c18919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ca6919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613d0a919061525b565b60405180910390a3600190509392505050565b5f600b905090565b60018054613d32906154df565b80601f0160208091040260200160405190810160405280929190818152602001828054613d5e906154df565b8015613da95780601f10613d8057610100808354040283529160200191613da9565b820191905f5260205f20905b815481529060010190602001808311613d8c57829003601f168201915b505050505081565b5f6015905090565b5f6029905090565b5f6038905090565b5f8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613e4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e4190615399565b60405180910390fd5b8160045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613e96919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254613ee9919061547f565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613f4d919061525b565b60405180910390a36001905092915050565b5f6028905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015613fe8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fdf90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156140a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161409a90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546140ef919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614142919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546141d0919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614234919061525b565b60405180910390a3600190509392505050565b5f6040905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156142d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016142c790615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561438b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161438290615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546143d7919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461442a919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546144b8919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161451c919061525b565b60405180910390a3600190509392505050565b5f6018905090565b5f600f905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156145c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016145b790615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561467b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161467290615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546146c7919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461471a919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546147a8919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161480c919061525b565b60405180910390a3600190509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410156148c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016148bb90615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054101561497f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161497690615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546149cb919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614a1e919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614aac919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614b10919061525b565b60405180910390a3600190509392505050565b5f6024905090565b5f601e905090565b5f6031905090565b5f6019905090565b5f6027905090565b6005602052815f5260405f20602052805f5260405f205f91509150505481565b5f603d905090565b5f6022905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614bfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614bf390615559565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c48919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614c9b919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614d29919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051614d8d919061525b565b60405180910390a3600190509392505050565b5f6007905090565b5f603e905090565b5f6020905090565b5f8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614e39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614e3090615399565b60405180910390fd5b8160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015614ef4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614eeb90615401565b60405180910390fd5b8160045f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f40919061544c565b925050819055508160045f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254614f93919061547f565b925050819055508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254615021919061544c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051615085919061525b565b60405180910390a3600190509392505050565b5f600e905090565b5f6012905090565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6150d5826150ac565b9050919050565b6150e5816150cb565b81146150ef575f5ffd5b50565b5f81359050615100816150dc565b92915050565b5f819050919050565b61511881615106565b8114615122575f5ffd5b50565b5f813590506151338161510f565b92915050565b5f5f5f606084860312156151505761514f6150a8565b5b5f61515d868287016150f2565b935050602061516e868287016150f2565b925050604061517f86828701615125565b9150509250925092565b5f8115159050919050565b61519d81615189565b82525050565b5f6020820190506151b65f830184615194565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6151fe826151bc565b61520881856151c6565b93506152188185602086016151d6565b615221816151e4565b840191505092915050565b5f6020820190508181035f83015261524481846151f4565b905092915050565b61525581615106565b82525050565b5f60208201905061526e5f83018461524c565b92915050565b5f5f6040838503121561528a576152896150a8565b5b5f615297858286016150f2565b92505060206152a885828601615125565b9150509250929050565b5f60ff82169050919050565b6152c7816152b2565b82525050565b5f6020820190506152e05f8301846152be565b92915050565b5f602082840312156152fb576152fa6150a8565b5b5f615308848285016150f2565b91505092915050565b5f5f60408385031215615327576153266150a8565b5b5f615334858286016150f2565b9250506020615345858286016150f2565b9150509250929050565b7f496e73756666696369656e742062616c616e63650000000000000000000000005f82015250565b5f6153836014836151c6565b915061538e8261534f565b602082019050919050565b5f6020820190508181035f8301526153b081615377565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e6365000000000000000000005f82015250565b5f6153eb6016836151c6565b91506153f6826153b7565b602082019050919050565b5f6020820190508181035f830152615418816153df565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61545682615106565b915061546183615106565b92508282039050818111156154795761547861541f565b5b92915050565b5f61548982615106565b915061549483615106565b92508282019050808211156154ac576154ab61541f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806154f657607f821691505b602082108103615509576155086154b2565b5b50919050565b7f41000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6155436001836151c6565b915061554e8261550f565b602082019050919050565b5f6020820190508181035f83015261557081615537565b9050919050565b7f42000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6155ab6001836151c6565b91506155b682615577565b602082019050919050565b5f6020820190508181035f8301526155d88161559f565b905091905056fea26469706673582212206fbf384dcd110eb4456b07e83a2c8a392433c7852a66dec9f8ebf3989cad1f6764736f6c634300081e0033", +// StateBloatTokenMetaData contains all meta data concerning the StateBloatToken contract. +var StateBloatTokenMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"PADDING_DATA\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy10\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy11\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy12\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy13\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy14\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy15\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy16\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy17\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy18\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy19\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy2\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy20\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy21\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy22\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy23\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy24\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy25\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy26\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy27\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy28\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy29\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy3\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy30\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy31\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy32\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy33\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy34\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy35\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy36\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy37\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy38\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy39\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy4\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy40\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy41\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy42\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy43\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy44\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy45\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy46\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy47\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy48\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy49\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy5\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy50\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy51\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy52\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy53\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy54\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy55\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy56\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy57\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy58\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy59\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy6\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy60\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy61\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy62\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy63\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy64\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy65\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy66\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy67\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy68\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy69\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy7\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy8\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dummy9\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"salt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom1\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom10\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom11\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom12\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom13\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom14\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom15\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom16\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom17\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom18\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom19\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom3\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom4\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom5\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom6\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom7\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom8\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom9\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801562000010575f80fd5b50604051620016f1380380620016f1833981016040819052620000339162000118565b60408051808201909152601181527029ba30ba3290213637b0ba102a37b5b2b760791b60208201525f90620000699082620001ce565b5060408051808201909152600381526214d09560ea1b6020820152600190620000939082620001ce565b506002805460ff191660129081179091556080829052620000b690600a620003a9565b620000c590620f4240620003c0565b6003819055335f81815260046020908152604080832085905551938452919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350620003da565b5f6020828403121562000129575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806200015957607f821691505b6020821081036200017857634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115620001c957805f5260205f20601f840160051c81016020851015620001a55750805b601f840160051c820191505b81811015620001c6575f8155600101620001b1565b50505b505050565b81516001600160401b03811115620001ea57620001ea62000130565b6200020281620001fb845462000144565b846200017e565b602080601f83116001811462000238575f8415620002205750858301515b5f19600386901b1c1916600185901b17855562000292565b5f85815260208120601f198616915b82811015620002685788860151825594840194600190910190840162000247565b50858210156200028657878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b634e487b7160e01b5f52601160045260245ffd5b600181815b80851115620002ee57815f1904821115620002d257620002d26200029a565b80851615620002e057918102915b93841c9390800290620002b3565b509250929050565b5f826200030657506001620003a3565b816200031457505f620003a3565b81600181146200032d5760028114620003385762000358565b6001915050620003a3565b60ff8411156200034c576200034c6200029a565b50506001821b620003a3565b5060208310610133831016604e8410600b84101617156200037d575081810a620003a3565b620003898383620002ae565b805f19048211156200039f576200039f6200029a565b0290505b92915050565b5f620003b960ff841683620002f6565b9392505050565b8082028115828204841417620003a357620003a36200029a565b6080516112fe620003f35f395f61089001526112fe5ff3fe608060405234801561000f575f80fd5b5060043610610630575f3560e01c8063657b6ef711610333578063ad8f4221116101b3578063d9bb3174116100fe578063ee1682b6116100a9578063f8716f1411610084578063f8716f141461093d578063faf35ced14610634578063fe7d599614610944578063ffbf04691461094b575f80fd5b8063ee1682b614610927578063f26c779b1461092f578063f5f5738114610936575f80fd5b8063e2d27530116100d9578063e2d2753014610906578063e8c927b31461090d578063eb4329c814610914575f80fd5b8063d9bb3174146108ce578063dc1d8a9b146108d5578063dd62ed3e146108dc575f80fd5b8063bfa0b1331161015e578063cfd6686311610139578063cfd66863146108b9578063d101dcd0146108c0578063d7419469146108c7575f80fd5b8063bfa0b1331461088b578063c2be97e314610634578063c958d4bf146108b2575f80fd5b8063b66dd7501161018e578063b66dd7501461087d578063b9a6d64514610884578063bb9bfe0614610634575f80fd5b8063ad8f42211461086f578063b1802b9a14610634578063b2bb360e14610876575f80fd5b80637dffdc321161027e57806395d89b4111610229578063a891d4d411610204578063a891d4d41461084e578063a9059cbb14610855578063aaa7af7014610868578063acc5aee914610634575f80fd5b806395d89b41146108385780639c5dfe73146108405780639df61a2514610847575f80fd5b80638619d607116102595780638619d6071461082a5780638789ca67146106345780638f4a840614610831575f80fd5b80637dffdc32146108155780637e5449371461081c5780637f34d94b14610823575f80fd5b806374f83d02116102de5780637a319c18116102b95780637a319c18146108075780637c66673e146106345780637c72ed0d1461080e575f80fd5b806374f83d02146107f257806377c0209e146107f9578063792c7f3e14610800575f80fd5b80636c12ed281161030e5780636c12ed281461063457806370a08231146107cc57806374e73fd3146107eb575f80fd5b8063657b6ef714610707578063672151fe146107be5780636abceacd146107c5575f80fd5b80633125f37a116104be5780634a2e93c611610409578063552a1b56116103b457806361b970eb1161038f57806361b970eb146107a2578063639ec53a146107a957806365473174146107b05780636578534c146107b7575f80fd5b8063552a1b561461063457806358b6a9bd146107945780635af92c051461079b575f80fd5b80634f5e5557116103e45780634f5e5557146107865780634f7bd75a1461063457806354c279201461078d575f80fd5b80634a2e93c6146107715780634b3c7f5f146107785780634e1dbb821461077f575f80fd5b80633ea117ce1161046957806342937dbd1161044457806342937dbd1461076357806343a6b92d1461076a57806344050a2814610634575f80fd5b80633ea117ce1461074e5780634128a85d14610755578063418b18161461075c575f80fd5b806339e0bd121161049957806339e0bd12146106345780633a131990146106345780633b6be45914610747575f80fd5b80633125f37a1461071a578063313ce5671461072157806334517f0b14610740575f80fd5b80631b17c65c1161057e57806321ecd7a3116105295780632545d8b7116105045780632545d8b7146106f95780632787325b14610700578063291c3bd714610707575f80fd5b806321ecd7a3146106eb578063239af2a5146106f257806323b872dd14610634575f80fd5b80631eaa7c52116105595780631eaa7c52146106d65780631f449589146106dd5780631fd298ec146106e4575f80fd5b80631b17c65c146106345780631bbffe6f146106345780631d527cde146106cf575f80fd5b806312901b42116105de57806318160ddd116105b957806318160ddd146106b857806319cf6a91146106c15780631a97f18e146106c8575f80fd5b806312901b42146106a357806313ebb5ec146106aa57806316a3045b146106b1575f80fd5b8063095ea7b31161060e578063095ea7b3146106825780630cb7a9e7146106955780631215a3ab1461069c575f80fd5b80630460faf61461063457806306fdde031461065c5780630717b16114610671575b5f80fd5b610647610642366004610fd2565b610952565b60405190151581526020015b60405180910390f35b610664610ba7565b604051610653919061100b565b602f5b604051908152602001610653565b610647610690366004611075565b610c32565b601b610674565b6005610674565b601a610674565b601d610674565b6033610674565b61067460035481565b6008610674565b6003610674565b6002610674565b6010610674565b6041610674565b6035610674565b602e610674565b602c610674565b6001610674565b6045610674565b610647610715366004610fd2565b610cab565b6034610674565b60025461072e9060ff1681565b60405160ff9091168152602001610653565b603c610674565b6004610674565b600c610674565b6006610674565b601c610674565b6032610674565b6023610674565b6011610674565b6021610674565b601f610674565b6026610674565b603a610674565b6009610674565b602a610674565b6014610674565b6025610674565b6013610674565b6043610674565b600d610674565b6017610674565b6106746107da36600461109d565b60046020525f908152604090205481565b6016610674565b6039610674565b603b610674565b6036610674565b603f610674565b602b610674565b6037610674565b600a610674565b602d610674565b6030610674565b600b610674565b610664610dd2565b6015610674565b6029610674565b6038610674565b610647610863366004611075565b610ddf565b6028610674565b6040610674565b6018610674565b600f610674565b6044610674565b6106747f000000000000000000000000000000000000000000000000000000000000000081565b6024610674565b601e610674565b6031610674565b6019610674565b6042610674565b6027610674565b6106746108ea3660046110bd565b600560209081525f928352604080842090915290825290205481565b603d610674565b6022610674565b610647610922366004610fd2565b610efd565b610664610f8b565b6007610674565b603e610674565b6020610674565b600e610674565b6012610674565b73ffffffffffffffffffffffffffffffffffffffff83165f908152600460205260408120548211156109e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e73756666696369656e742062616c616e636500000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84165f908152600560209081526040808320338452909152902054821115610a7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e73756666696369656e7420616c6c6f77616e63650000000000000000000060448201526064016109dc565b73ffffffffffffffffffffffffffffffffffffffff84165f9081526004602052604081208054849290610ab290849061111b565b909155505073ffffffffffffffffffffffffffffffffffffffff83165f9081526004602052604081208054849290610aeb90849061112e565b909155505073ffffffffffffffffffffffffffffffffffffffff84165f90815260056020908152604080832033845290915281208054849290610b2f90849061111b565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610b9591815260200190565b60405180910390a35060019392505050565b5f8054610bb390611141565b80601f0160208091040260200160405190810160405280929190818152602001828054610bdf90611141565b8015610c2a5780601f10610c0157610100808354040283529160200191610c2a565b820191905f5260205f20905b815481529060010190602001808311610c0d57829003601f168201915b505050505081565b335f81815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610c999086815260200190565b60405180910390a35060015b92915050565b73ffffffffffffffffffffffffffffffffffffffff83165f90815260046020526040812054821115610d39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f410000000000000000000000000000000000000000000000000000000000000060448201526064016109dc565b73ffffffffffffffffffffffffffffffffffffffff84165f908152600560209081526040808320338452909152902054821115610a7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f420000000000000000000000000000000000000000000000000000000000000060448201526064016109dc565b60018054610bb390611141565b335f90815260046020526040812054821115610e57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e73756666696369656e742062616c616e636500000000000000000000000060448201526064016109dc565b335f9081526004602052604081208054849290610e7590849061111b565b909155505073ffffffffffffffffffffffffffffffffffffffff83165f9081526004602052604081208054849290610eae90849061112e565b909155505060405182815273ffffffffffffffffffffffffffffffffffffffff84169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610c99565b73ffffffffffffffffffffffffffffffffffffffff83165f90815260046020526040812054821115610a7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f410000000000000000000000000000000000000000000000000000000000000060448201526064016109dc565b6040518061016001604052806101368152602001611193610136913981565b803573ffffffffffffffffffffffffffffffffffffffff81168114610fcd575f80fd5b919050565b5f805f60608486031215610fe4575f80fd5b610fed84610faa565b9250610ffb60208501610faa565b9150604084013590509250925092565b5f602080835283518060208501525f5b818110156110375785810183015185820160400152820161101b565b505f6040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b5f8060408385031215611086575f80fd5b61108f83610faa565b946020939093013593505050565b5f602082840312156110ad575f80fd5b6110b682610faa565b9392505050565b5f80604083850312156110ce575f80fd5b6110d783610faa565b91506110e560208401610faa565b90509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610ca557610ca56110ee565b80820180821115610ca557610ca56110ee565b600181811c9082168061115557607f821691505b60208210810361118c577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5091905056fe41414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141a2646970667358221220c70035169e4d38ee509e85ab2f5566c500caae43b66c105f4552e44745217d5f64736f6c63430008160033", } -// ContractABI is the input ABI used to generate the binding from. -// Deprecated: Use ContractMetaData.ABI instead. -var ContractABI = ContractMetaData.ABI +// StateBloatTokenABI is the input ABI used to generate the binding from. +// Deprecated: Use StateBloatTokenMetaData.ABI instead. +var StateBloatTokenABI = StateBloatTokenMetaData.ABI -// ContractBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ContractMetaData.Bin instead. -var ContractBin = ContractMetaData.Bin +// StateBloatTokenBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use StateBloatTokenMetaData.Bin instead. +var StateBloatTokenBin = StateBloatTokenMetaData.Bin -// DeployContract deploys a new Ethereum contract, binding an instance of Contract to it. -func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend, _salt *big.Int) (common.Address, *types.Transaction, *Contract, error) { - parsed, err := ContractMetaData.GetAbi() +// DeployStateBloatToken deploys a new Ethereum contract, binding an instance of StateBloatToken to it. +func DeployStateBloatToken(auth *bind.TransactOpts, backend bind.ContractBackend, _salt *big.Int) (common.Address, *types.Transaction, *StateBloatToken, error) { + parsed, err := StateBloatTokenMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -53,111 +53,111 @@ func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend, _salt return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ContractBin), backend, _salt) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(StateBloatTokenBin), backend, _salt) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil + return address, tx, &StateBloatToken{StateBloatTokenCaller: StateBloatTokenCaller{contract: contract}, StateBloatTokenTransactor: StateBloatTokenTransactor{contract: contract}, StateBloatTokenFilterer: StateBloatTokenFilterer{contract: contract}}, nil } -// Contract is an auto generated Go binding around an Ethereum contract. -type Contract struct { - ContractCaller // Read-only binding to the contract - ContractTransactor // Write-only binding to the contract - ContractFilterer // Log filterer for contract events +// StateBloatToken is an auto generated Go binding around an Ethereum contract. +type StateBloatToken struct { + StateBloatTokenCaller // Read-only binding to the contract + StateBloatTokenTransactor // Write-only binding to the contract + StateBloatTokenFilterer // Log filterer for contract events } -// ContractCaller is an auto generated read-only Go binding around an Ethereum contract. -type ContractCaller struct { +// StateBloatTokenCaller is an auto generated read-only Go binding around an Ethereum contract. +type StateBloatTokenCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ContractTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ContractTransactor struct { +// StateBloatTokenTransactor is an auto generated write-only Go binding around an Ethereum contract. +type StateBloatTokenTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ContractFilterer struct { +// StateBloatTokenFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type StateBloatTokenFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ContractSession is an auto generated Go binding around an Ethereum contract, +// StateBloatTokenSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ContractSession struct { - Contract *Contract // Generic contract binding to set the session for +type StateBloatTokenSession struct { + Contract *StateBloatToken // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// StateBloatTokenCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ContractCallerSession struct { - Contract *ContractCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type StateBloatTokenCallerSession struct { + Contract *StateBloatTokenCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// StateBloatTokenTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ContractTransactorSession struct { - Contract *ContractTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type StateBloatTokenTransactorSession struct { + Contract *StateBloatTokenTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ContractRaw is an auto generated low-level Go binding around an Ethereum contract. -type ContractRaw struct { - Contract *Contract // Generic contract binding to access the raw methods on +// StateBloatTokenRaw is an auto generated low-level Go binding around an Ethereum contract. +type StateBloatTokenRaw struct { + Contract *StateBloatToken // Generic contract binding to access the raw methods on } -// ContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ContractCallerRaw struct { - Contract *ContractCaller // Generic read-only contract binding to access the raw methods on +// StateBloatTokenCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type StateBloatTokenCallerRaw struct { + Contract *StateBloatTokenCaller // Generic read-only contract binding to access the raw methods on } -// ContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ContractTransactorRaw struct { - Contract *ContractTransactor // Generic write-only contract binding to access the raw methods on +// StateBloatTokenTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type StateBloatTokenTransactorRaw struct { + Contract *StateBloatTokenTransactor // Generic write-only contract binding to access the raw methods on } -// NewContract creates a new instance of Contract, bound to a specific deployed contract. -func NewContract(address common.Address, backend bind.ContractBackend) (*Contract, error) { - contract, err := bindContract(address, backend, backend, backend) +// NewStateBloatToken creates a new instance of StateBloatToken, bound to a specific deployed contract. +func NewStateBloatToken(address common.Address, backend bind.ContractBackend) (*StateBloatToken, error) { + contract, err := bindStateBloatToken(address, backend, backend, backend) if err != nil { return nil, err } - return &Contract{ContractCaller: ContractCaller{contract: contract}, ContractTransactor: ContractTransactor{contract: contract}, ContractFilterer: ContractFilterer{contract: contract}}, nil + return &StateBloatToken{StateBloatTokenCaller: StateBloatTokenCaller{contract: contract}, StateBloatTokenTransactor: StateBloatTokenTransactor{contract: contract}, StateBloatTokenFilterer: StateBloatTokenFilterer{contract: contract}}, nil } -// NewContractCaller creates a new read-only instance of Contract, bound to a specific deployed contract. -func NewContractCaller(address common.Address, caller bind.ContractCaller) (*ContractCaller, error) { - contract, err := bindContract(address, caller, nil, nil) +// NewStateBloatTokenCaller creates a new read-only instance of StateBloatToken, bound to a specific deployed contract. +func NewStateBloatTokenCaller(address common.Address, caller bind.ContractCaller) (*StateBloatTokenCaller, error) { + contract, err := bindStateBloatToken(address, caller, nil, nil) if err != nil { return nil, err } - return &ContractCaller{contract: contract}, nil + return &StateBloatTokenCaller{contract: contract}, nil } -// NewContractTransactor creates a new write-only instance of Contract, bound to a specific deployed contract. -func NewContractTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractTransactor, error) { - contract, err := bindContract(address, nil, transactor, nil) +// NewStateBloatTokenTransactor creates a new write-only instance of StateBloatToken, bound to a specific deployed contract. +func NewStateBloatTokenTransactor(address common.Address, transactor bind.ContractTransactor) (*StateBloatTokenTransactor, error) { + contract, err := bindStateBloatToken(address, nil, transactor, nil) if err != nil { return nil, err } - return &ContractTransactor{contract: contract}, nil + return &StateBloatTokenTransactor{contract: contract}, nil } -// NewContractFilterer creates a new log filterer instance of Contract, bound to a specific deployed contract. -func NewContractFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractFilterer, error) { - contract, err := bindContract(address, nil, nil, filterer) +// NewStateBloatTokenFilterer creates a new log filterer instance of StateBloatToken, bound to a specific deployed contract. +func NewStateBloatTokenFilterer(address common.Address, filterer bind.ContractFilterer) (*StateBloatTokenFilterer, error) { + contract, err := bindStateBloatToken(address, nil, nil, filterer) if err != nil { return nil, err } - return &ContractFilterer{contract: contract}, nil + return &StateBloatTokenFilterer{contract: contract}, nil } -// bindContract binds a generic wrapper to an already deployed contract. -func bindContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := ContractMetaData.GetAbi() +// bindStateBloatToken binds a generic wrapper to an already deployed contract. +func bindStateBloatToken(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := StateBloatTokenMetaData.GetAbi() if err != nil { return nil, err } @@ -168,46 +168,77 @@ func bindContract(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Contract *ContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.ContractCaller.contract.Call(opts, result, method, params...) +func (_StateBloatToken *StateBloatTokenRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _StateBloatToken.Contract.StateBloatTokenCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Contract *ContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transfer(opts) +func (_StateBloatToken *StateBloatTokenRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _StateBloatToken.Contract.StateBloatTokenTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.ContractTransactor.contract.Transact(opts, method, params...) +func (_StateBloatToken *StateBloatTokenRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _StateBloatToken.Contract.StateBloatTokenTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Contract *ContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Contract.Contract.contract.Call(opts, result, method, params...) +func (_StateBloatToken *StateBloatTokenCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _StateBloatToken.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Contract *ContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Contract.Contract.contract.Transfer(opts) +func (_StateBloatToken *StateBloatTokenTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _StateBloatToken.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Contract *ContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Contract.Contract.contract.Transact(opts, method, params...) +func (_StateBloatToken *StateBloatTokenTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _StateBloatToken.Contract.contract.Transact(opts, method, params...) +} + +// PADDINGDATA is a free data retrieval call binding the contract method 0xee1682b6. +// +// Solidity: function PADDING_DATA() view returns(string) +func (_StateBloatToken *StateBloatTokenCaller) PADDINGDATA(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _StateBloatToken.contract.Call(opts, &out, "PADDING_DATA") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// PADDINGDATA is a free data retrieval call binding the contract method 0xee1682b6. +// +// Solidity: function PADDING_DATA() view returns(string) +func (_StateBloatToken *StateBloatTokenSession) PADDINGDATA() (string, error) { + return _StateBloatToken.Contract.PADDINGDATA(&_StateBloatToken.CallOpts) +} + +// PADDINGDATA is a free data retrieval call binding the contract method 0xee1682b6. +// +// Solidity: function PADDING_DATA() view returns(string) +func (_StateBloatToken *StateBloatTokenCallerSession) PADDINGDATA() (string, error) { + return _StateBloatToken.Contract.PADDINGDATA(&_StateBloatToken.CallOpts) } // Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. // // Solidity: function allowance(address , address ) view returns(uint256) -func (_Contract *ContractCaller) Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "allowance", arg0, arg1) + err := _StateBloatToken.contract.Call(opts, &out, "allowance", arg0, arg1) if err != nil { return *new(*big.Int), err @@ -222,23 +253,23 @@ func (_Contract *ContractCaller) Allowance(opts *bind.CallOpts, arg0 common.Addr // Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. // // Solidity: function allowance(address , address ) view returns(uint256) -func (_Contract *ContractSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { - return _Contract.Contract.Allowance(&_Contract.CallOpts, arg0, arg1) +func (_StateBloatToken *StateBloatTokenSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _StateBloatToken.Contract.Allowance(&_StateBloatToken.CallOpts, arg0, arg1) } // Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. // // Solidity: function allowance(address , address ) view returns(uint256) -func (_Contract *ContractCallerSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { - return _Contract.Contract.Allowance(&_Contract.CallOpts, arg0, arg1) +func (_StateBloatToken *StateBloatTokenCallerSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _StateBloatToken.Contract.Allowance(&_StateBloatToken.CallOpts, arg0, arg1) } // BalanceOf is a free data retrieval call binding the contract method 0x70a08231. // // Solidity: function balanceOf(address ) view returns(uint256) -func (_Contract *ContractCaller) BalanceOf(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) BalanceOf(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "balanceOf", arg0) + err := _StateBloatToken.contract.Call(opts, &out, "balanceOf", arg0) if err != nil { return *new(*big.Int), err @@ -253,23 +284,23 @@ func (_Contract *ContractCaller) BalanceOf(opts *bind.CallOpts, arg0 common.Addr // BalanceOf is a free data retrieval call binding the contract method 0x70a08231. // // Solidity: function balanceOf(address ) view returns(uint256) -func (_Contract *ContractSession) BalanceOf(arg0 common.Address) (*big.Int, error) { - return _Contract.Contract.BalanceOf(&_Contract.CallOpts, arg0) +func (_StateBloatToken *StateBloatTokenSession) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _StateBloatToken.Contract.BalanceOf(&_StateBloatToken.CallOpts, arg0) } // BalanceOf is a free data retrieval call binding the contract method 0x70a08231. // // Solidity: function balanceOf(address ) view returns(uint256) -func (_Contract *ContractCallerSession) BalanceOf(arg0 common.Address) (*big.Int, error) { - return _Contract.Contract.BalanceOf(&_Contract.CallOpts, arg0) +func (_StateBloatToken *StateBloatTokenCallerSession) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _StateBloatToken.Contract.BalanceOf(&_StateBloatToken.CallOpts, arg0) } // Decimals is a free data retrieval call binding the contract method 0x313ce567. // // Solidity: function decimals() view returns(uint8) -func (_Contract *ContractCaller) Decimals(opts *bind.CallOpts) (uint8, error) { +func (_StateBloatToken *StateBloatTokenCaller) Decimals(opts *bind.CallOpts) (uint8, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "decimals") + err := _StateBloatToken.contract.Call(opts, &out, "decimals") if err != nil { return *new(uint8), err @@ -284,23 +315,23 @@ func (_Contract *ContractCaller) Decimals(opts *bind.CallOpts) (uint8, error) { // Decimals is a free data retrieval call binding the contract method 0x313ce567. // // Solidity: function decimals() view returns(uint8) -func (_Contract *ContractSession) Decimals() (uint8, error) { - return _Contract.Contract.Decimals(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Decimals() (uint8, error) { + return _StateBloatToken.Contract.Decimals(&_StateBloatToken.CallOpts) } // Decimals is a free data retrieval call binding the contract method 0x313ce567. // // Solidity: function decimals() view returns(uint8) -func (_Contract *ContractCallerSession) Decimals() (uint8, error) { - return _Contract.Contract.Decimals(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Decimals() (uint8, error) { + return _StateBloatToken.Contract.Decimals(&_StateBloatToken.CallOpts) } // Dummy1 is a free data retrieval call binding the contract method 0x2545d8b7. // // Solidity: function dummy1() pure returns(uint256) -func (_Contract *ContractCaller) Dummy1(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy1(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy1") + err := _StateBloatToken.contract.Call(opts, &out, "dummy1") if err != nil { return *new(*big.Int), err @@ -315,23 +346,23 @@ func (_Contract *ContractCaller) Dummy1(opts *bind.CallOpts) (*big.Int, error) { // Dummy1 is a free data retrieval call binding the contract method 0x2545d8b7. // // Solidity: function dummy1() pure returns(uint256) -func (_Contract *ContractSession) Dummy1() (*big.Int, error) { - return _Contract.Contract.Dummy1(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy1() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy1(&_StateBloatToken.CallOpts) } // Dummy1 is a free data retrieval call binding the contract method 0x2545d8b7. // // Solidity: function dummy1() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy1() (*big.Int, error) { - return _Contract.Contract.Dummy1(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy1() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy1(&_StateBloatToken.CallOpts) } // Dummy10 is a free data retrieval call binding the contract method 0x7e544937. // // Solidity: function dummy10() pure returns(uint256) -func (_Contract *ContractCaller) Dummy10(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy10(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy10") + err := _StateBloatToken.contract.Call(opts, &out, "dummy10") if err != nil { return *new(*big.Int), err @@ -346,23 +377,23 @@ func (_Contract *ContractCaller) Dummy10(opts *bind.CallOpts) (*big.Int, error) // Dummy10 is a free data retrieval call binding the contract method 0x7e544937. // // Solidity: function dummy10() pure returns(uint256) -func (_Contract *ContractSession) Dummy10() (*big.Int, error) { - return _Contract.Contract.Dummy10(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy10() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy10(&_StateBloatToken.CallOpts) } // Dummy10 is a free data retrieval call binding the contract method 0x7e544937. // // Solidity: function dummy10() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy10() (*big.Int, error) { - return _Contract.Contract.Dummy10(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy10() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy10(&_StateBloatToken.CallOpts) } // Dummy11 is a free data retrieval call binding the contract method 0x8f4a8406. // // Solidity: function dummy11() pure returns(uint256) -func (_Contract *ContractCaller) Dummy11(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy11(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy11") + err := _StateBloatToken.contract.Call(opts, &out, "dummy11") if err != nil { return *new(*big.Int), err @@ -377,23 +408,23 @@ func (_Contract *ContractCaller) Dummy11(opts *bind.CallOpts) (*big.Int, error) // Dummy11 is a free data retrieval call binding the contract method 0x8f4a8406. // // Solidity: function dummy11() pure returns(uint256) -func (_Contract *ContractSession) Dummy11() (*big.Int, error) { - return _Contract.Contract.Dummy11(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy11() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy11(&_StateBloatToken.CallOpts) } // Dummy11 is a free data retrieval call binding the contract method 0x8f4a8406. // // Solidity: function dummy11() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy11() (*big.Int, error) { - return _Contract.Contract.Dummy11(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy11() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy11(&_StateBloatToken.CallOpts) } // Dummy12 is a free data retrieval call binding the contract method 0x3ea117ce. // // Solidity: function dummy12() pure returns(uint256) -func (_Contract *ContractCaller) Dummy12(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy12(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy12") + err := _StateBloatToken.contract.Call(opts, &out, "dummy12") if err != nil { return *new(*big.Int), err @@ -408,23 +439,23 @@ func (_Contract *ContractCaller) Dummy12(opts *bind.CallOpts) (*big.Int, error) // Dummy12 is a free data retrieval call binding the contract method 0x3ea117ce. // // Solidity: function dummy12() pure returns(uint256) -func (_Contract *ContractSession) Dummy12() (*big.Int, error) { - return _Contract.Contract.Dummy12(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy12() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy12(&_StateBloatToken.CallOpts) } // Dummy12 is a free data retrieval call binding the contract method 0x3ea117ce. // // Solidity: function dummy12() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy12() (*big.Int, error) { - return _Contract.Contract.Dummy12(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy12() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy12(&_StateBloatToken.CallOpts) } // Dummy13 is a free data retrieval call binding the contract method 0x672151fe. // // Solidity: function dummy13() pure returns(uint256) -func (_Contract *ContractCaller) Dummy13(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy13(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy13") + err := _StateBloatToken.contract.Call(opts, &out, "dummy13") if err != nil { return *new(*big.Int), err @@ -439,23 +470,23 @@ func (_Contract *ContractCaller) Dummy13(opts *bind.CallOpts) (*big.Int, error) // Dummy13 is a free data retrieval call binding the contract method 0x672151fe. // // Solidity: function dummy13() pure returns(uint256) -func (_Contract *ContractSession) Dummy13() (*big.Int, error) { - return _Contract.Contract.Dummy13(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy13() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy13(&_StateBloatToken.CallOpts) } // Dummy13 is a free data retrieval call binding the contract method 0x672151fe. // // Solidity: function dummy13() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy13() (*big.Int, error) { - return _Contract.Contract.Dummy13(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy13() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy13(&_StateBloatToken.CallOpts) } // Dummy14 is a free data retrieval call binding the contract method 0xfe7d5996. // // Solidity: function dummy14() pure returns(uint256) -func (_Contract *ContractCaller) Dummy14(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy14(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy14") + err := _StateBloatToken.contract.Call(opts, &out, "dummy14") if err != nil { return *new(*big.Int), err @@ -470,23 +501,23 @@ func (_Contract *ContractCaller) Dummy14(opts *bind.CallOpts) (*big.Int, error) // Dummy14 is a free data retrieval call binding the contract method 0xfe7d5996. // // Solidity: function dummy14() pure returns(uint256) -func (_Contract *ContractSession) Dummy14() (*big.Int, error) { - return _Contract.Contract.Dummy14(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy14() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy14(&_StateBloatToken.CallOpts) } // Dummy14 is a free data retrieval call binding the contract method 0xfe7d5996. // // Solidity: function dummy14() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy14() (*big.Int, error) { - return _Contract.Contract.Dummy14(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy14() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy14(&_StateBloatToken.CallOpts) } // Dummy15 is a free data retrieval call binding the contract method 0xb66dd750. // // Solidity: function dummy15() pure returns(uint256) -func (_Contract *ContractCaller) Dummy15(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy15(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy15") + err := _StateBloatToken.contract.Call(opts, &out, "dummy15") if err != nil { return *new(*big.Int), err @@ -501,23 +532,23 @@ func (_Contract *ContractCaller) Dummy15(opts *bind.CallOpts) (*big.Int, error) // Dummy15 is a free data retrieval call binding the contract method 0xb66dd750. // // Solidity: function dummy15() pure returns(uint256) -func (_Contract *ContractSession) Dummy15() (*big.Int, error) { - return _Contract.Contract.Dummy15(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy15() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy15(&_StateBloatToken.CallOpts) } // Dummy15 is a free data retrieval call binding the contract method 0xb66dd750. // // Solidity: function dummy15() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy15() (*big.Int, error) { - return _Contract.Contract.Dummy15(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy15() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy15(&_StateBloatToken.CallOpts) } // Dummy16 is a free data retrieval call binding the contract method 0x1eaa7c52. // // Solidity: function dummy16() pure returns(uint256) -func (_Contract *ContractCaller) Dummy16(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy16(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy16") + err := _StateBloatToken.contract.Call(opts, &out, "dummy16") if err != nil { return *new(*big.Int), err @@ -532,23 +563,23 @@ func (_Contract *ContractCaller) Dummy16(opts *bind.CallOpts) (*big.Int, error) // Dummy16 is a free data retrieval call binding the contract method 0x1eaa7c52. // // Solidity: function dummy16() pure returns(uint256) -func (_Contract *ContractSession) Dummy16() (*big.Int, error) { - return _Contract.Contract.Dummy16(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy16() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy16(&_StateBloatToken.CallOpts) } // Dummy16 is a free data retrieval call binding the contract method 0x1eaa7c52. // // Solidity: function dummy16() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy16() (*big.Int, error) { - return _Contract.Contract.Dummy16(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy16() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy16(&_StateBloatToken.CallOpts) } // Dummy17 is a free data retrieval call binding the contract method 0x4a2e93c6. // // Solidity: function dummy17() pure returns(uint256) -func (_Contract *ContractCaller) Dummy17(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy17(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy17") + err := _StateBloatToken.contract.Call(opts, &out, "dummy17") if err != nil { return *new(*big.Int), err @@ -563,23 +594,23 @@ func (_Contract *ContractCaller) Dummy17(opts *bind.CallOpts) (*big.Int, error) // Dummy17 is a free data retrieval call binding the contract method 0x4a2e93c6. // // Solidity: function dummy17() pure returns(uint256) -func (_Contract *ContractSession) Dummy17() (*big.Int, error) { - return _Contract.Contract.Dummy17(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy17() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy17(&_StateBloatToken.CallOpts) } // Dummy17 is a free data retrieval call binding the contract method 0x4a2e93c6. // // Solidity: function dummy17() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy17() (*big.Int, error) { - return _Contract.Contract.Dummy17(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy17() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy17(&_StateBloatToken.CallOpts) } // Dummy18 is a free data retrieval call binding the contract method 0xffbf0469. // // Solidity: function dummy18() pure returns(uint256) -func (_Contract *ContractCaller) Dummy18(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy18(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy18") + err := _StateBloatToken.contract.Call(opts, &out, "dummy18") if err != nil { return *new(*big.Int), err @@ -594,23 +625,23 @@ func (_Contract *ContractCaller) Dummy18(opts *bind.CallOpts) (*big.Int, error) // Dummy18 is a free data retrieval call binding the contract method 0xffbf0469. // // Solidity: function dummy18() pure returns(uint256) -func (_Contract *ContractSession) Dummy18() (*big.Int, error) { - return _Contract.Contract.Dummy18(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy18() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy18(&_StateBloatToken.CallOpts) } // Dummy18 is a free data retrieval call binding the contract method 0xffbf0469. // // Solidity: function dummy18() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy18() (*big.Int, error) { - return _Contract.Contract.Dummy18(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy18() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy18(&_StateBloatToken.CallOpts) } // Dummy19 is a free data retrieval call binding the contract method 0x65473174. // // Solidity: function dummy19() pure returns(uint256) -func (_Contract *ContractCaller) Dummy19(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy19(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy19") + err := _StateBloatToken.contract.Call(opts, &out, "dummy19") if err != nil { return *new(*big.Int), err @@ -625,23 +656,23 @@ func (_Contract *ContractCaller) Dummy19(opts *bind.CallOpts) (*big.Int, error) // Dummy19 is a free data retrieval call binding the contract method 0x65473174. // // Solidity: function dummy19() pure returns(uint256) -func (_Contract *ContractSession) Dummy19() (*big.Int, error) { - return _Contract.Contract.Dummy19(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy19() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy19(&_StateBloatToken.CallOpts) } // Dummy19 is a free data retrieval call binding the contract method 0x65473174. // // Solidity: function dummy19() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy19() (*big.Int, error) { - return _Contract.Contract.Dummy19(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy19() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy19(&_StateBloatToken.CallOpts) } // Dummy2 is a free data retrieval call binding the contract method 0x1d527cde. // // Solidity: function dummy2() pure returns(uint256) -func (_Contract *ContractCaller) Dummy2(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy2(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy2") + err := _StateBloatToken.contract.Call(opts, &out, "dummy2") if err != nil { return *new(*big.Int), err @@ -656,23 +687,23 @@ func (_Contract *ContractCaller) Dummy2(opts *bind.CallOpts) (*big.Int, error) { // Dummy2 is a free data retrieval call binding the contract method 0x1d527cde. // // Solidity: function dummy2() pure returns(uint256) -func (_Contract *ContractSession) Dummy2() (*big.Int, error) { - return _Contract.Contract.Dummy2(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy2() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy2(&_StateBloatToken.CallOpts) } // Dummy2 is a free data retrieval call binding the contract method 0x1d527cde. // // Solidity: function dummy2() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy2() (*big.Int, error) { - return _Contract.Contract.Dummy2(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy2() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy2(&_StateBloatToken.CallOpts) } // Dummy20 is a free data retrieval call binding the contract method 0x61b970eb. // // Solidity: function dummy20() pure returns(uint256) -func (_Contract *ContractCaller) Dummy20(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy20(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy20") + err := _StateBloatToken.contract.Call(opts, &out, "dummy20") if err != nil { return *new(*big.Int), err @@ -687,23 +718,23 @@ func (_Contract *ContractCaller) Dummy20(opts *bind.CallOpts) (*big.Int, error) // Dummy20 is a free data retrieval call binding the contract method 0x61b970eb. // // Solidity: function dummy20() pure returns(uint256) -func (_Contract *ContractSession) Dummy20() (*big.Int, error) { - return _Contract.Contract.Dummy20(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy20() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy20(&_StateBloatToken.CallOpts) } // Dummy20 is a free data retrieval call binding the contract method 0x61b970eb. // // Solidity: function dummy20() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy20() (*big.Int, error) { - return _Contract.Contract.Dummy20(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy20() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy20(&_StateBloatToken.CallOpts) } // Dummy21 is a free data retrieval call binding the contract method 0x9c5dfe73. // // Solidity: function dummy21() pure returns(uint256) -func (_Contract *ContractCaller) Dummy21(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy21(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy21") + err := _StateBloatToken.contract.Call(opts, &out, "dummy21") if err != nil { return *new(*big.Int), err @@ -718,23 +749,23 @@ func (_Contract *ContractCaller) Dummy21(opts *bind.CallOpts) (*big.Int, error) // Dummy21 is a free data retrieval call binding the contract method 0x9c5dfe73. // // Solidity: function dummy21() pure returns(uint256) -func (_Contract *ContractSession) Dummy21() (*big.Int, error) { - return _Contract.Contract.Dummy21(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy21() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy21(&_StateBloatToken.CallOpts) } // Dummy21 is a free data retrieval call binding the contract method 0x9c5dfe73. // // Solidity: function dummy21() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy21() (*big.Int, error) { - return _Contract.Contract.Dummy21(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy21() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy21(&_StateBloatToken.CallOpts) } // Dummy22 is a free data retrieval call binding the contract method 0x74e73fd3. // // Solidity: function dummy22() pure returns(uint256) -func (_Contract *ContractCaller) Dummy22(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy22(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy22") + err := _StateBloatToken.contract.Call(opts, &out, "dummy22") if err != nil { return *new(*big.Int), err @@ -749,23 +780,23 @@ func (_Contract *ContractCaller) Dummy22(opts *bind.CallOpts) (*big.Int, error) // Dummy22 is a free data retrieval call binding the contract method 0x74e73fd3. // // Solidity: function dummy22() pure returns(uint256) -func (_Contract *ContractSession) Dummy22() (*big.Int, error) { - return _Contract.Contract.Dummy22(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy22() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy22(&_StateBloatToken.CallOpts) } // Dummy22 is a free data retrieval call binding the contract method 0x74e73fd3. // // Solidity: function dummy22() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy22() (*big.Int, error) { - return _Contract.Contract.Dummy22(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy22() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy22(&_StateBloatToken.CallOpts) } // Dummy23 is a free data retrieval call binding the contract method 0x6abceacd. // // Solidity: function dummy23() pure returns(uint256) -func (_Contract *ContractCaller) Dummy23(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy23(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy23") + err := _StateBloatToken.contract.Call(opts, &out, "dummy23") if err != nil { return *new(*big.Int), err @@ -780,23 +811,23 @@ func (_Contract *ContractCaller) Dummy23(opts *bind.CallOpts) (*big.Int, error) // Dummy23 is a free data retrieval call binding the contract method 0x6abceacd. // // Solidity: function dummy23() pure returns(uint256) -func (_Contract *ContractSession) Dummy23() (*big.Int, error) { - return _Contract.Contract.Dummy23(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy23() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy23(&_StateBloatToken.CallOpts) } // Dummy23 is a free data retrieval call binding the contract method 0x6abceacd. // // Solidity: function dummy23() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy23() (*big.Int, error) { - return _Contract.Contract.Dummy23(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy23() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy23(&_StateBloatToken.CallOpts) } // Dummy24 is a free data retrieval call binding the contract method 0xb2bb360e. // // Solidity: function dummy24() pure returns(uint256) -func (_Contract *ContractCaller) Dummy24(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy24(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy24") + err := _StateBloatToken.contract.Call(opts, &out, "dummy24") if err != nil { return *new(*big.Int), err @@ -811,23 +842,23 @@ func (_Contract *ContractCaller) Dummy24(opts *bind.CallOpts) (*big.Int, error) // Dummy24 is a free data retrieval call binding the contract method 0xb2bb360e. // // Solidity: function dummy24() pure returns(uint256) -func (_Contract *ContractSession) Dummy24() (*big.Int, error) { - return _Contract.Contract.Dummy24(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy24() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy24(&_StateBloatToken.CallOpts) } // Dummy24 is a free data retrieval call binding the contract method 0xb2bb360e. // // Solidity: function dummy24() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy24() (*big.Int, error) { - return _Contract.Contract.Dummy24(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy24() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy24(&_StateBloatToken.CallOpts) } // Dummy25 is a free data retrieval call binding the contract method 0xd7419469. // // Solidity: function dummy25() pure returns(uint256) -func (_Contract *ContractCaller) Dummy25(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy25(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy25") + err := _StateBloatToken.contract.Call(opts, &out, "dummy25") if err != nil { return *new(*big.Int), err @@ -842,23 +873,23 @@ func (_Contract *ContractCaller) Dummy25(opts *bind.CallOpts) (*big.Int, error) // Dummy25 is a free data retrieval call binding the contract method 0xd7419469. // // Solidity: function dummy25() pure returns(uint256) -func (_Contract *ContractSession) Dummy25() (*big.Int, error) { - return _Contract.Contract.Dummy25(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy25() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy25(&_StateBloatToken.CallOpts) } // Dummy25 is a free data retrieval call binding the contract method 0xd7419469. // // Solidity: function dummy25() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy25() (*big.Int, error) { - return _Contract.Contract.Dummy25(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy25() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy25(&_StateBloatToken.CallOpts) } // Dummy26 is a free data retrieval call binding the contract method 0x12901b42. // // Solidity: function dummy26() pure returns(uint256) -func (_Contract *ContractCaller) Dummy26(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy26(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy26") + err := _StateBloatToken.contract.Call(opts, &out, "dummy26") if err != nil { return *new(*big.Int), err @@ -873,23 +904,23 @@ func (_Contract *ContractCaller) Dummy26(opts *bind.CallOpts) (*big.Int, error) // Dummy26 is a free data retrieval call binding the contract method 0x12901b42. // // Solidity: function dummy26() pure returns(uint256) -func (_Contract *ContractSession) Dummy26() (*big.Int, error) { - return _Contract.Contract.Dummy26(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy26() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy26(&_StateBloatToken.CallOpts) } // Dummy26 is a free data retrieval call binding the contract method 0x12901b42. // // Solidity: function dummy26() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy26() (*big.Int, error) { - return _Contract.Contract.Dummy26(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy26() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy26(&_StateBloatToken.CallOpts) } // Dummy27 is a free data retrieval call binding the contract method 0x0cb7a9e7. // // Solidity: function dummy27() pure returns(uint256) -func (_Contract *ContractCaller) Dummy27(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy27(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy27") + err := _StateBloatToken.contract.Call(opts, &out, "dummy27") if err != nil { return *new(*big.Int), err @@ -904,23 +935,23 @@ func (_Contract *ContractCaller) Dummy27(opts *bind.CallOpts) (*big.Int, error) // Dummy27 is a free data retrieval call binding the contract method 0x0cb7a9e7. // // Solidity: function dummy27() pure returns(uint256) -func (_Contract *ContractSession) Dummy27() (*big.Int, error) { - return _Contract.Contract.Dummy27(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy27() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy27(&_StateBloatToken.CallOpts) } // Dummy27 is a free data retrieval call binding the contract method 0x0cb7a9e7. // // Solidity: function dummy27() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy27() (*big.Int, error) { - return _Contract.Contract.Dummy27(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy27() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy27(&_StateBloatToken.CallOpts) } // Dummy28 is a free data retrieval call binding the contract method 0x418b1816. // // Solidity: function dummy28() pure returns(uint256) -func (_Contract *ContractCaller) Dummy28(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy28(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy28") + err := _StateBloatToken.contract.Call(opts, &out, "dummy28") if err != nil { return *new(*big.Int), err @@ -935,23 +966,23 @@ func (_Contract *ContractCaller) Dummy28(opts *bind.CallOpts) (*big.Int, error) // Dummy28 is a free data retrieval call binding the contract method 0x418b1816. // // Solidity: function dummy28() pure returns(uint256) -func (_Contract *ContractSession) Dummy28() (*big.Int, error) { - return _Contract.Contract.Dummy28(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy28() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy28(&_StateBloatToken.CallOpts) } // Dummy28 is a free data retrieval call binding the contract method 0x418b1816. // // Solidity: function dummy28() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy28() (*big.Int, error) { - return _Contract.Contract.Dummy28(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy28() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy28(&_StateBloatToken.CallOpts) } // Dummy29 is a free data retrieval call binding the contract method 0x13ebb5ec. // // Solidity: function dummy29() pure returns(uint256) -func (_Contract *ContractCaller) Dummy29(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy29(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy29") + err := _StateBloatToken.contract.Call(opts, &out, "dummy29") if err != nil { return *new(*big.Int), err @@ -966,23 +997,23 @@ func (_Contract *ContractCaller) Dummy29(opts *bind.CallOpts) (*big.Int, error) // Dummy29 is a free data retrieval call binding the contract method 0x13ebb5ec. // // Solidity: function dummy29() pure returns(uint256) -func (_Contract *ContractSession) Dummy29() (*big.Int, error) { - return _Contract.Contract.Dummy29(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy29() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy29(&_StateBloatToken.CallOpts) } // Dummy29 is a free data retrieval call binding the contract method 0x13ebb5ec. // // Solidity: function dummy29() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy29() (*big.Int, error) { - return _Contract.Contract.Dummy29(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy29() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy29(&_StateBloatToken.CallOpts) } // Dummy3 is a free data retrieval call binding the contract method 0x1a97f18e. // // Solidity: function dummy3() pure returns(uint256) -func (_Contract *ContractCaller) Dummy3(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy3(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy3") + err := _StateBloatToken.contract.Call(opts, &out, "dummy3") if err != nil { return *new(*big.Int), err @@ -997,23 +1028,23 @@ func (_Contract *ContractCaller) Dummy3(opts *bind.CallOpts) (*big.Int, error) { // Dummy3 is a free data retrieval call binding the contract method 0x1a97f18e. // // Solidity: function dummy3() pure returns(uint256) -func (_Contract *ContractSession) Dummy3() (*big.Int, error) { - return _Contract.Contract.Dummy3(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy3() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy3(&_StateBloatToken.CallOpts) } // Dummy3 is a free data retrieval call binding the contract method 0x1a97f18e. // // Solidity: function dummy3() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy3() (*big.Int, error) { - return _Contract.Contract.Dummy3(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy3() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy3(&_StateBloatToken.CallOpts) } // Dummy30 is a free data retrieval call binding the contract method 0xcfd66863. // // Solidity: function dummy30() pure returns(uint256) -func (_Contract *ContractCaller) Dummy30(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy30(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy30") + err := _StateBloatToken.contract.Call(opts, &out, "dummy30") if err != nil { return *new(*big.Int), err @@ -1028,23 +1059,23 @@ func (_Contract *ContractCaller) Dummy30(opts *bind.CallOpts) (*big.Int, error) // Dummy30 is a free data retrieval call binding the contract method 0xcfd66863. // // Solidity: function dummy30() pure returns(uint256) -func (_Contract *ContractSession) Dummy30() (*big.Int, error) { - return _Contract.Contract.Dummy30(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy30() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy30(&_StateBloatToken.CallOpts) } // Dummy30 is a free data retrieval call binding the contract method 0xcfd66863. // // Solidity: function dummy30() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy30() (*big.Int, error) { - return _Contract.Contract.Dummy30(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy30() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy30(&_StateBloatToken.CallOpts) } // Dummy31 is a free data retrieval call binding the contract method 0x4e1dbb82. // // Solidity: function dummy31() pure returns(uint256) -func (_Contract *ContractCaller) Dummy31(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy31(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy31") + err := _StateBloatToken.contract.Call(opts, &out, "dummy31") if err != nil { return *new(*big.Int), err @@ -1059,23 +1090,23 @@ func (_Contract *ContractCaller) Dummy31(opts *bind.CallOpts) (*big.Int, error) // Dummy31 is a free data retrieval call binding the contract method 0x4e1dbb82. // // Solidity: function dummy31() pure returns(uint256) -func (_Contract *ContractSession) Dummy31() (*big.Int, error) { - return _Contract.Contract.Dummy31(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy31() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy31(&_StateBloatToken.CallOpts) } // Dummy31 is a free data retrieval call binding the contract method 0x4e1dbb82. // // Solidity: function dummy31() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy31() (*big.Int, error) { - return _Contract.Contract.Dummy31(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy31() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy31(&_StateBloatToken.CallOpts) } // Dummy32 is a free data retrieval call binding the contract method 0xf8716f14. // // Solidity: function dummy32() pure returns(uint256) -func (_Contract *ContractCaller) Dummy32(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy32(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy32") + err := _StateBloatToken.contract.Call(opts, &out, "dummy32") if err != nil { return *new(*big.Int), err @@ -1090,23 +1121,23 @@ func (_Contract *ContractCaller) Dummy32(opts *bind.CallOpts) (*big.Int, error) // Dummy32 is a free data retrieval call binding the contract method 0xf8716f14. // // Solidity: function dummy32() pure returns(uint256) -func (_Contract *ContractSession) Dummy32() (*big.Int, error) { - return _Contract.Contract.Dummy32(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy32() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy32(&_StateBloatToken.CallOpts) } // Dummy32 is a free data retrieval call binding the contract method 0xf8716f14. // // Solidity: function dummy32() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy32() (*big.Int, error) { - return _Contract.Contract.Dummy32(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy32() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy32(&_StateBloatToken.CallOpts) } // Dummy33 is a free data retrieval call binding the contract method 0x4b3c7f5f. // // Solidity: function dummy33() pure returns(uint256) -func (_Contract *ContractCaller) Dummy33(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy33(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy33") + err := _StateBloatToken.contract.Call(opts, &out, "dummy33") if err != nil { return *new(*big.Int), err @@ -1121,23 +1152,23 @@ func (_Contract *ContractCaller) Dummy33(opts *bind.CallOpts) (*big.Int, error) // Dummy33 is a free data retrieval call binding the contract method 0x4b3c7f5f. // // Solidity: function dummy33() pure returns(uint256) -func (_Contract *ContractSession) Dummy33() (*big.Int, error) { - return _Contract.Contract.Dummy33(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy33() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy33(&_StateBloatToken.CallOpts) } // Dummy33 is a free data retrieval call binding the contract method 0x4b3c7f5f. // // Solidity: function dummy33() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy33() (*big.Int, error) { - return _Contract.Contract.Dummy33(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy33() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy33(&_StateBloatToken.CallOpts) } // Dummy34 is a free data retrieval call binding the contract method 0xe8c927b3. // // Solidity: function dummy34() pure returns(uint256) -func (_Contract *ContractCaller) Dummy34(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy34(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy34") + err := _StateBloatToken.contract.Call(opts, &out, "dummy34") if err != nil { return *new(*big.Int), err @@ -1152,23 +1183,23 @@ func (_Contract *ContractCaller) Dummy34(opts *bind.CallOpts) (*big.Int, error) // Dummy34 is a free data retrieval call binding the contract method 0xe8c927b3. // // Solidity: function dummy34() pure returns(uint256) -func (_Contract *ContractSession) Dummy34() (*big.Int, error) { - return _Contract.Contract.Dummy34(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy34() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy34(&_StateBloatToken.CallOpts) } // Dummy34 is a free data retrieval call binding the contract method 0xe8c927b3. // // Solidity: function dummy34() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy34() (*big.Int, error) { - return _Contract.Contract.Dummy34(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy34() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy34(&_StateBloatToken.CallOpts) } // Dummy35 is a free data retrieval call binding the contract method 0x43a6b92d. // // Solidity: function dummy35() pure returns(uint256) -func (_Contract *ContractCaller) Dummy35(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy35(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy35") + err := _StateBloatToken.contract.Call(opts, &out, "dummy35") if err != nil { return *new(*big.Int), err @@ -1183,23 +1214,23 @@ func (_Contract *ContractCaller) Dummy35(opts *bind.CallOpts) (*big.Int, error) // Dummy35 is a free data retrieval call binding the contract method 0x43a6b92d. // // Solidity: function dummy35() pure returns(uint256) -func (_Contract *ContractSession) Dummy35() (*big.Int, error) { - return _Contract.Contract.Dummy35(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy35() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy35(&_StateBloatToken.CallOpts) } // Dummy35 is a free data retrieval call binding the contract method 0x43a6b92d. // // Solidity: function dummy35() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy35() (*big.Int, error) { - return _Contract.Contract.Dummy35(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy35() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy35(&_StateBloatToken.CallOpts) } // Dummy36 is a free data retrieval call binding the contract method 0xc958d4bf. // // Solidity: function dummy36() pure returns(uint256) -func (_Contract *ContractCaller) Dummy36(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy36(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy36") + err := _StateBloatToken.contract.Call(opts, &out, "dummy36") if err != nil { return *new(*big.Int), err @@ -1214,23 +1245,23 @@ func (_Contract *ContractCaller) Dummy36(opts *bind.CallOpts) (*big.Int, error) // Dummy36 is a free data retrieval call binding the contract method 0xc958d4bf. // // Solidity: function dummy36() pure returns(uint256) -func (_Contract *ContractSession) Dummy36() (*big.Int, error) { - return _Contract.Contract.Dummy36(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy36() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy36(&_StateBloatToken.CallOpts) } // Dummy36 is a free data retrieval call binding the contract method 0xc958d4bf. // // Solidity: function dummy36() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy36() (*big.Int, error) { - return _Contract.Contract.Dummy36(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy36() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy36(&_StateBloatToken.CallOpts) } // Dummy37 is a free data retrieval call binding the contract method 0x639ec53a. // // Solidity: function dummy37() pure returns(uint256) -func (_Contract *ContractCaller) Dummy37(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy37(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy37") + err := _StateBloatToken.contract.Call(opts, &out, "dummy37") if err != nil { return *new(*big.Int), err @@ -1245,23 +1276,23 @@ func (_Contract *ContractCaller) Dummy37(opts *bind.CallOpts) (*big.Int, error) // Dummy37 is a free data retrieval call binding the contract method 0x639ec53a. // // Solidity: function dummy37() pure returns(uint256) -func (_Contract *ContractSession) Dummy37() (*big.Int, error) { - return _Contract.Contract.Dummy37(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy37() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy37(&_StateBloatToken.CallOpts) } // Dummy37 is a free data retrieval call binding the contract method 0x639ec53a. // // Solidity: function dummy37() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy37() (*big.Int, error) { - return _Contract.Contract.Dummy37(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy37() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy37(&_StateBloatToken.CallOpts) } // Dummy38 is a free data retrieval call binding the contract method 0x4f5e5557. // // Solidity: function dummy38() pure returns(uint256) -func (_Contract *ContractCaller) Dummy38(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy38(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy38") + err := _StateBloatToken.contract.Call(opts, &out, "dummy38") if err != nil { return *new(*big.Int), err @@ -1276,23 +1307,23 @@ func (_Contract *ContractCaller) Dummy38(opts *bind.CallOpts) (*big.Int, error) // Dummy38 is a free data retrieval call binding the contract method 0x4f5e5557. // // Solidity: function dummy38() pure returns(uint256) -func (_Contract *ContractSession) Dummy38() (*big.Int, error) { - return _Contract.Contract.Dummy38(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy38() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy38(&_StateBloatToken.CallOpts) } // Dummy38 is a free data retrieval call binding the contract method 0x4f5e5557. // // Solidity: function dummy38() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy38() (*big.Int, error) { - return _Contract.Contract.Dummy38(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy38() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy38(&_StateBloatToken.CallOpts) } // Dummy39 is a free data retrieval call binding the contract method 0xdc1d8a9b. // // Solidity: function dummy39() pure returns(uint256) -func (_Contract *ContractCaller) Dummy39(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy39(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy39") + err := _StateBloatToken.contract.Call(opts, &out, "dummy39") if err != nil { return *new(*big.Int), err @@ -1307,23 +1338,23 @@ func (_Contract *ContractCaller) Dummy39(opts *bind.CallOpts) (*big.Int, error) // Dummy39 is a free data retrieval call binding the contract method 0xdc1d8a9b. // // Solidity: function dummy39() pure returns(uint256) -func (_Contract *ContractSession) Dummy39() (*big.Int, error) { - return _Contract.Contract.Dummy39(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy39() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy39(&_StateBloatToken.CallOpts) } // Dummy39 is a free data retrieval call binding the contract method 0xdc1d8a9b. // // Solidity: function dummy39() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy39() (*big.Int, error) { - return _Contract.Contract.Dummy39(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy39() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy39(&_StateBloatToken.CallOpts) } // Dummy4 is a free data retrieval call binding the contract method 0x3b6be459. // // Solidity: function dummy4() pure returns(uint256) -func (_Contract *ContractCaller) Dummy4(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy4(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy4") + err := _StateBloatToken.contract.Call(opts, &out, "dummy4") if err != nil { return *new(*big.Int), err @@ -1338,23 +1369,23 @@ func (_Contract *ContractCaller) Dummy4(opts *bind.CallOpts) (*big.Int, error) { // Dummy4 is a free data retrieval call binding the contract method 0x3b6be459. // // Solidity: function dummy4() pure returns(uint256) -func (_Contract *ContractSession) Dummy4() (*big.Int, error) { - return _Contract.Contract.Dummy4(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy4() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy4(&_StateBloatToken.CallOpts) } // Dummy4 is a free data retrieval call binding the contract method 0x3b6be459. // // Solidity: function dummy4() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy4() (*big.Int, error) { - return _Contract.Contract.Dummy4(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy4() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy4(&_StateBloatToken.CallOpts) } // Dummy40 is a free data retrieval call binding the contract method 0xaaa7af70. // // Solidity: function dummy40() pure returns(uint256) -func (_Contract *ContractCaller) Dummy40(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy40(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy40") + err := _StateBloatToken.contract.Call(opts, &out, "dummy40") if err != nil { return *new(*big.Int), err @@ -1369,23 +1400,23 @@ func (_Contract *ContractCaller) Dummy40(opts *bind.CallOpts) (*big.Int, error) // Dummy40 is a free data retrieval call binding the contract method 0xaaa7af70. // // Solidity: function dummy40() pure returns(uint256) -func (_Contract *ContractSession) Dummy40() (*big.Int, error) { - return _Contract.Contract.Dummy40(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy40() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy40(&_StateBloatToken.CallOpts) } // Dummy40 is a free data retrieval call binding the contract method 0xaaa7af70. // // Solidity: function dummy40() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy40() (*big.Int, error) { - return _Contract.Contract.Dummy40(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy40() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy40(&_StateBloatToken.CallOpts) } // Dummy41 is a free data retrieval call binding the contract method 0x9df61a25. // // Solidity: function dummy41() pure returns(uint256) -func (_Contract *ContractCaller) Dummy41(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy41(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy41") + err := _StateBloatToken.contract.Call(opts, &out, "dummy41") if err != nil { return *new(*big.Int), err @@ -1400,23 +1431,23 @@ func (_Contract *ContractCaller) Dummy41(opts *bind.CallOpts) (*big.Int, error) // Dummy41 is a free data retrieval call binding the contract method 0x9df61a25. // // Solidity: function dummy41() pure returns(uint256) -func (_Contract *ContractSession) Dummy41() (*big.Int, error) { - return _Contract.Contract.Dummy41(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy41() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy41(&_StateBloatToken.CallOpts) } // Dummy41 is a free data retrieval call binding the contract method 0x9df61a25. // // Solidity: function dummy41() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy41() (*big.Int, error) { - return _Contract.Contract.Dummy41(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy41() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy41(&_StateBloatToken.CallOpts) } // Dummy42 is a free data retrieval call binding the contract method 0x5af92c05. // // Solidity: function dummy42() pure returns(uint256) -func (_Contract *ContractCaller) Dummy42(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy42(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy42") + err := _StateBloatToken.contract.Call(opts, &out, "dummy42") if err != nil { return *new(*big.Int), err @@ -1431,23 +1462,23 @@ func (_Contract *ContractCaller) Dummy42(opts *bind.CallOpts) (*big.Int, error) // Dummy42 is a free data retrieval call binding the contract method 0x5af92c05. // // Solidity: function dummy42() pure returns(uint256) -func (_Contract *ContractSession) Dummy42() (*big.Int, error) { - return _Contract.Contract.Dummy42(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy42() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy42(&_StateBloatToken.CallOpts) } // Dummy42 is a free data retrieval call binding the contract method 0x5af92c05. // // Solidity: function dummy42() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy42() (*big.Int, error) { - return _Contract.Contract.Dummy42(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy42() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy42(&_StateBloatToken.CallOpts) } // Dummy43 is a free data retrieval call binding the contract method 0x7c72ed0d. // // Solidity: function dummy43() pure returns(uint256) -func (_Contract *ContractCaller) Dummy43(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy43(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy43") + err := _StateBloatToken.contract.Call(opts, &out, "dummy43") if err != nil { return *new(*big.Int), err @@ -1462,23 +1493,23 @@ func (_Contract *ContractCaller) Dummy43(opts *bind.CallOpts) (*big.Int, error) // Dummy43 is a free data retrieval call binding the contract method 0x7c72ed0d. // // Solidity: function dummy43() pure returns(uint256) -func (_Contract *ContractSession) Dummy43() (*big.Int, error) { - return _Contract.Contract.Dummy43(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy43() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy43(&_StateBloatToken.CallOpts) } // Dummy43 is a free data retrieval call binding the contract method 0x7c72ed0d. // // Solidity: function dummy43() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy43() (*big.Int, error) { - return _Contract.Contract.Dummy43(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy43() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy43(&_StateBloatToken.CallOpts) } // Dummy44 is a free data retrieval call binding the contract method 0x239af2a5. // // Solidity: function dummy44() pure returns(uint256) -func (_Contract *ContractCaller) Dummy44(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy44(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy44") + err := _StateBloatToken.contract.Call(opts, &out, "dummy44") if err != nil { return *new(*big.Int), err @@ -1493,23 +1524,23 @@ func (_Contract *ContractCaller) Dummy44(opts *bind.CallOpts) (*big.Int, error) // Dummy44 is a free data retrieval call binding the contract method 0x239af2a5. // // Solidity: function dummy44() pure returns(uint256) -func (_Contract *ContractSession) Dummy44() (*big.Int, error) { - return _Contract.Contract.Dummy44(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy44() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy44(&_StateBloatToken.CallOpts) } // Dummy44 is a free data retrieval call binding the contract method 0x239af2a5. // // Solidity: function dummy44() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy44() (*big.Int, error) { - return _Contract.Contract.Dummy44(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy44() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy44(&_StateBloatToken.CallOpts) } // Dummy45 is a free data retrieval call binding the contract method 0x7f34d94b. // // Solidity: function dummy45() pure returns(uint256) -func (_Contract *ContractCaller) Dummy45(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy45(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy45") + err := _StateBloatToken.contract.Call(opts, &out, "dummy45") if err != nil { return *new(*big.Int), err @@ -1524,23 +1555,23 @@ func (_Contract *ContractCaller) Dummy45(opts *bind.CallOpts) (*big.Int, error) // Dummy45 is a free data retrieval call binding the contract method 0x7f34d94b. // // Solidity: function dummy45() pure returns(uint256) -func (_Contract *ContractSession) Dummy45() (*big.Int, error) { - return _Contract.Contract.Dummy45(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy45() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy45(&_StateBloatToken.CallOpts) } // Dummy45 is a free data retrieval call binding the contract method 0x7f34d94b. // // Solidity: function dummy45() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy45() (*big.Int, error) { - return _Contract.Contract.Dummy45(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy45() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy45(&_StateBloatToken.CallOpts) } // Dummy46 is a free data retrieval call binding the contract method 0x21ecd7a3. // // Solidity: function dummy46() pure returns(uint256) -func (_Contract *ContractCaller) Dummy46(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy46(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy46") + err := _StateBloatToken.contract.Call(opts, &out, "dummy46") if err != nil { return *new(*big.Int), err @@ -1555,23 +1586,23 @@ func (_Contract *ContractCaller) Dummy46(opts *bind.CallOpts) (*big.Int, error) // Dummy46 is a free data retrieval call binding the contract method 0x21ecd7a3. // // Solidity: function dummy46() pure returns(uint256) -func (_Contract *ContractSession) Dummy46() (*big.Int, error) { - return _Contract.Contract.Dummy46(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy46() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy46(&_StateBloatToken.CallOpts) } // Dummy46 is a free data retrieval call binding the contract method 0x21ecd7a3. // // Solidity: function dummy46() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy46() (*big.Int, error) { - return _Contract.Contract.Dummy46(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy46() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy46(&_StateBloatToken.CallOpts) } // Dummy47 is a free data retrieval call binding the contract method 0x0717b161. // // Solidity: function dummy47() pure returns(uint256) -func (_Contract *ContractCaller) Dummy47(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy47(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy47") + err := _StateBloatToken.contract.Call(opts, &out, "dummy47") if err != nil { return *new(*big.Int), err @@ -1586,23 +1617,23 @@ func (_Contract *ContractCaller) Dummy47(opts *bind.CallOpts) (*big.Int, error) // Dummy47 is a free data retrieval call binding the contract method 0x0717b161. // // Solidity: function dummy47() pure returns(uint256) -func (_Contract *ContractSession) Dummy47() (*big.Int, error) { - return _Contract.Contract.Dummy47(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy47() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy47(&_StateBloatToken.CallOpts) } // Dummy47 is a free data retrieval call binding the contract method 0x0717b161. // // Solidity: function dummy47() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy47() (*big.Int, error) { - return _Contract.Contract.Dummy47(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy47() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy47(&_StateBloatToken.CallOpts) } // Dummy48 is a free data retrieval call binding the contract method 0x8619d607. // // Solidity: function dummy48() pure returns(uint256) -func (_Contract *ContractCaller) Dummy48(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy48(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy48") + err := _StateBloatToken.contract.Call(opts, &out, "dummy48") if err != nil { return *new(*big.Int), err @@ -1617,23 +1648,23 @@ func (_Contract *ContractCaller) Dummy48(opts *bind.CallOpts) (*big.Int, error) // Dummy48 is a free data retrieval call binding the contract method 0x8619d607. // // Solidity: function dummy48() pure returns(uint256) -func (_Contract *ContractSession) Dummy48() (*big.Int, error) { - return _Contract.Contract.Dummy48(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy48() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy48(&_StateBloatToken.CallOpts) } // Dummy48 is a free data retrieval call binding the contract method 0x8619d607. // // Solidity: function dummy48() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy48() (*big.Int, error) { - return _Contract.Contract.Dummy48(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy48() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy48(&_StateBloatToken.CallOpts) } // Dummy49 is a free data retrieval call binding the contract method 0xd101dcd0. // // Solidity: function dummy49() pure returns(uint256) -func (_Contract *ContractCaller) Dummy49(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy49(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy49") + err := _StateBloatToken.contract.Call(opts, &out, "dummy49") if err != nil { return *new(*big.Int), err @@ -1648,23 +1679,23 @@ func (_Contract *ContractCaller) Dummy49(opts *bind.CallOpts) (*big.Int, error) // Dummy49 is a free data retrieval call binding the contract method 0xd101dcd0. // // Solidity: function dummy49() pure returns(uint256) -func (_Contract *ContractSession) Dummy49() (*big.Int, error) { - return _Contract.Contract.Dummy49(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy49() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy49(&_StateBloatToken.CallOpts) } // Dummy49 is a free data retrieval call binding the contract method 0xd101dcd0. // // Solidity: function dummy49() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy49() (*big.Int, error) { - return _Contract.Contract.Dummy49(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy49() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy49(&_StateBloatToken.CallOpts) } // Dummy5 is a free data retrieval call binding the contract method 0x1215a3ab. // // Solidity: function dummy5() pure returns(uint256) -func (_Contract *ContractCaller) Dummy5(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy5(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy5") + err := _StateBloatToken.contract.Call(opts, &out, "dummy5") if err != nil { return *new(*big.Int), err @@ -1679,23 +1710,23 @@ func (_Contract *ContractCaller) Dummy5(opts *bind.CallOpts) (*big.Int, error) { // Dummy5 is a free data retrieval call binding the contract method 0x1215a3ab. // // Solidity: function dummy5() pure returns(uint256) -func (_Contract *ContractSession) Dummy5() (*big.Int, error) { - return _Contract.Contract.Dummy5(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy5() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy5(&_StateBloatToken.CallOpts) } // Dummy5 is a free data retrieval call binding the contract method 0x1215a3ab. // // Solidity: function dummy5() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy5() (*big.Int, error) { - return _Contract.Contract.Dummy5(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy5() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy5(&_StateBloatToken.CallOpts) } // Dummy50 is a free data retrieval call binding the contract method 0x42937dbd. // // Solidity: function dummy50() pure returns(uint256) -func (_Contract *ContractCaller) Dummy50(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy50(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy50") + err := _StateBloatToken.contract.Call(opts, &out, "dummy50") if err != nil { return *new(*big.Int), err @@ -1710,23 +1741,23 @@ func (_Contract *ContractCaller) Dummy50(opts *bind.CallOpts) (*big.Int, error) // Dummy50 is a free data retrieval call binding the contract method 0x42937dbd. // // Solidity: function dummy50() pure returns(uint256) -func (_Contract *ContractSession) Dummy50() (*big.Int, error) { - return _Contract.Contract.Dummy50(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy50() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy50(&_StateBloatToken.CallOpts) } // Dummy50 is a free data retrieval call binding the contract method 0x42937dbd. // // Solidity: function dummy50() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy50() (*big.Int, error) { - return _Contract.Contract.Dummy50(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy50() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy50(&_StateBloatToken.CallOpts) } // Dummy51 is a free data retrieval call binding the contract method 0x16a3045b. // // Solidity: function dummy51() pure returns(uint256) -func (_Contract *ContractCaller) Dummy51(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy51(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy51") + err := _StateBloatToken.contract.Call(opts, &out, "dummy51") if err != nil { return *new(*big.Int), err @@ -1741,23 +1772,23 @@ func (_Contract *ContractCaller) Dummy51(opts *bind.CallOpts) (*big.Int, error) // Dummy51 is a free data retrieval call binding the contract method 0x16a3045b. // // Solidity: function dummy51() pure returns(uint256) -func (_Contract *ContractSession) Dummy51() (*big.Int, error) { - return _Contract.Contract.Dummy51(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy51() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy51(&_StateBloatToken.CallOpts) } // Dummy51 is a free data retrieval call binding the contract method 0x16a3045b. // // Solidity: function dummy51() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy51() (*big.Int, error) { - return _Contract.Contract.Dummy51(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy51() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy51(&_StateBloatToken.CallOpts) } // Dummy52 is a free data retrieval call binding the contract method 0x3125f37a. // // Solidity: function dummy52() pure returns(uint256) -func (_Contract *ContractCaller) Dummy52(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy52(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy52") + err := _StateBloatToken.contract.Call(opts, &out, "dummy52") if err != nil { return *new(*big.Int), err @@ -1772,23 +1803,23 @@ func (_Contract *ContractCaller) Dummy52(opts *bind.CallOpts) (*big.Int, error) // Dummy52 is a free data retrieval call binding the contract method 0x3125f37a. // // Solidity: function dummy52() pure returns(uint256) -func (_Contract *ContractSession) Dummy52() (*big.Int, error) { - return _Contract.Contract.Dummy52(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy52() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy52(&_StateBloatToken.CallOpts) } // Dummy52 is a free data retrieval call binding the contract method 0x3125f37a. // // Solidity: function dummy52() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy52() (*big.Int, error) { - return _Contract.Contract.Dummy52(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy52() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy52(&_StateBloatToken.CallOpts) } // Dummy53 is a free data retrieval call binding the contract method 0x1fd298ec. // // Solidity: function dummy53() pure returns(uint256) -func (_Contract *ContractCaller) Dummy53(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy53(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy53") + err := _StateBloatToken.contract.Call(opts, &out, "dummy53") if err != nil { return *new(*big.Int), err @@ -1803,23 +1834,23 @@ func (_Contract *ContractCaller) Dummy53(opts *bind.CallOpts) (*big.Int, error) // Dummy53 is a free data retrieval call binding the contract method 0x1fd298ec. // // Solidity: function dummy53() pure returns(uint256) -func (_Contract *ContractSession) Dummy53() (*big.Int, error) { - return _Contract.Contract.Dummy53(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy53() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy53(&_StateBloatToken.CallOpts) } // Dummy53 is a free data retrieval call binding the contract method 0x1fd298ec. // // Solidity: function dummy53() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy53() (*big.Int, error) { - return _Contract.Contract.Dummy53(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy53() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy53(&_StateBloatToken.CallOpts) } // Dummy54 is a free data retrieval call binding the contract method 0x792c7f3e. // // Solidity: function dummy54() pure returns(uint256) -func (_Contract *ContractCaller) Dummy54(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy54(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy54") + err := _StateBloatToken.contract.Call(opts, &out, "dummy54") if err != nil { return *new(*big.Int), err @@ -1834,23 +1865,23 @@ func (_Contract *ContractCaller) Dummy54(opts *bind.CallOpts) (*big.Int, error) // Dummy54 is a free data retrieval call binding the contract method 0x792c7f3e. // // Solidity: function dummy54() pure returns(uint256) -func (_Contract *ContractSession) Dummy54() (*big.Int, error) { - return _Contract.Contract.Dummy54(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy54() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy54(&_StateBloatToken.CallOpts) } // Dummy54 is a free data retrieval call binding the contract method 0x792c7f3e. // // Solidity: function dummy54() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy54() (*big.Int, error) { - return _Contract.Contract.Dummy54(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy54() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy54(&_StateBloatToken.CallOpts) } // Dummy55 is a free data retrieval call binding the contract method 0x7dffdc32. // // Solidity: function dummy55() pure returns(uint256) -func (_Contract *ContractCaller) Dummy55(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy55(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy55") + err := _StateBloatToken.contract.Call(opts, &out, "dummy55") if err != nil { return *new(*big.Int), err @@ -1865,23 +1896,23 @@ func (_Contract *ContractCaller) Dummy55(opts *bind.CallOpts) (*big.Int, error) // Dummy55 is a free data retrieval call binding the contract method 0x7dffdc32. // // Solidity: function dummy55() pure returns(uint256) -func (_Contract *ContractSession) Dummy55() (*big.Int, error) { - return _Contract.Contract.Dummy55(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy55() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy55(&_StateBloatToken.CallOpts) } // Dummy55 is a free data retrieval call binding the contract method 0x7dffdc32. // // Solidity: function dummy55() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy55() (*big.Int, error) { - return _Contract.Contract.Dummy55(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy55() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy55(&_StateBloatToken.CallOpts) } // Dummy56 is a free data retrieval call binding the contract method 0xa891d4d4. // // Solidity: function dummy56() pure returns(uint256) -func (_Contract *ContractCaller) Dummy56(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy56(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy56") + err := _StateBloatToken.contract.Call(opts, &out, "dummy56") if err != nil { return *new(*big.Int), err @@ -1896,23 +1927,23 @@ func (_Contract *ContractCaller) Dummy56(opts *bind.CallOpts) (*big.Int, error) // Dummy56 is a free data retrieval call binding the contract method 0xa891d4d4. // // Solidity: function dummy56() pure returns(uint256) -func (_Contract *ContractSession) Dummy56() (*big.Int, error) { - return _Contract.Contract.Dummy56(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy56() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy56(&_StateBloatToken.CallOpts) } // Dummy56 is a free data retrieval call binding the contract method 0xa891d4d4. // // Solidity: function dummy56() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy56() (*big.Int, error) { - return _Contract.Contract.Dummy56(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy56() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy56(&_StateBloatToken.CallOpts) } // Dummy57 is a free data retrieval call binding the contract method 0x74f83d02. // // Solidity: function dummy57() pure returns(uint256) -func (_Contract *ContractCaller) Dummy57(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy57(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy57") + err := _StateBloatToken.contract.Call(opts, &out, "dummy57") if err != nil { return *new(*big.Int), err @@ -1927,23 +1958,23 @@ func (_Contract *ContractCaller) Dummy57(opts *bind.CallOpts) (*big.Int, error) // Dummy57 is a free data retrieval call binding the contract method 0x74f83d02. // // Solidity: function dummy57() pure returns(uint256) -func (_Contract *ContractSession) Dummy57() (*big.Int, error) { - return _Contract.Contract.Dummy57(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy57() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy57(&_StateBloatToken.CallOpts) } // Dummy57 is a free data retrieval call binding the contract method 0x74f83d02. // // Solidity: function dummy57() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy57() (*big.Int, error) { - return _Contract.Contract.Dummy57(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy57() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy57(&_StateBloatToken.CallOpts) } // Dummy58 is a free data retrieval call binding the contract method 0x54c27920. // // Solidity: function dummy58() pure returns(uint256) -func (_Contract *ContractCaller) Dummy58(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy58(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy58") + err := _StateBloatToken.contract.Call(opts, &out, "dummy58") if err != nil { return *new(*big.Int), err @@ -1958,23 +1989,23 @@ func (_Contract *ContractCaller) Dummy58(opts *bind.CallOpts) (*big.Int, error) // Dummy58 is a free data retrieval call binding the contract method 0x54c27920. // // Solidity: function dummy58() pure returns(uint256) -func (_Contract *ContractSession) Dummy58() (*big.Int, error) { - return _Contract.Contract.Dummy58(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy58() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy58(&_StateBloatToken.CallOpts) } // Dummy58 is a free data retrieval call binding the contract method 0x54c27920. // // Solidity: function dummy58() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy58() (*big.Int, error) { - return _Contract.Contract.Dummy58(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy58() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy58(&_StateBloatToken.CallOpts) } // Dummy59 is a free data retrieval call binding the contract method 0x77c0209e. // // Solidity: function dummy59() pure returns(uint256) -func (_Contract *ContractCaller) Dummy59(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy59(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy59") + err := _StateBloatToken.contract.Call(opts, &out, "dummy59") if err != nil { return *new(*big.Int), err @@ -1989,23 +2020,23 @@ func (_Contract *ContractCaller) Dummy59(opts *bind.CallOpts) (*big.Int, error) // Dummy59 is a free data retrieval call binding the contract method 0x77c0209e. // // Solidity: function dummy59() pure returns(uint256) -func (_Contract *ContractSession) Dummy59() (*big.Int, error) { - return _Contract.Contract.Dummy59(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy59() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy59(&_StateBloatToken.CallOpts) } // Dummy59 is a free data retrieval call binding the contract method 0x77c0209e. // // Solidity: function dummy59() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy59() (*big.Int, error) { - return _Contract.Contract.Dummy59(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy59() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy59(&_StateBloatToken.CallOpts) } // Dummy6 is a free data retrieval call binding the contract method 0x4128a85d. // // Solidity: function dummy6() pure returns(uint256) -func (_Contract *ContractCaller) Dummy6(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy6(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy6") + err := _StateBloatToken.contract.Call(opts, &out, "dummy6") if err != nil { return *new(*big.Int), err @@ -2020,23 +2051,23 @@ func (_Contract *ContractCaller) Dummy6(opts *bind.CallOpts) (*big.Int, error) { // Dummy6 is a free data retrieval call binding the contract method 0x4128a85d. // // Solidity: function dummy6() pure returns(uint256) -func (_Contract *ContractSession) Dummy6() (*big.Int, error) { - return _Contract.Contract.Dummy6(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy6() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy6(&_StateBloatToken.CallOpts) } // Dummy6 is a free data retrieval call binding the contract method 0x4128a85d. // // Solidity: function dummy6() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy6() (*big.Int, error) { - return _Contract.Contract.Dummy6(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy6() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy6(&_StateBloatToken.CallOpts) } // Dummy60 is a free data retrieval call binding the contract method 0x34517f0b. // // Solidity: function dummy60() pure returns(uint256) -func (_Contract *ContractCaller) Dummy60(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy60(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy60") + err := _StateBloatToken.contract.Call(opts, &out, "dummy60") if err != nil { return *new(*big.Int), err @@ -2051,23 +2082,23 @@ func (_Contract *ContractCaller) Dummy60(opts *bind.CallOpts) (*big.Int, error) // Dummy60 is a free data retrieval call binding the contract method 0x34517f0b. // // Solidity: function dummy60() pure returns(uint256) -func (_Contract *ContractSession) Dummy60() (*big.Int, error) { - return _Contract.Contract.Dummy60(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy60() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy60(&_StateBloatToken.CallOpts) } // Dummy60 is a free data retrieval call binding the contract method 0x34517f0b. // // Solidity: function dummy60() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy60() (*big.Int, error) { - return _Contract.Contract.Dummy60(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy60() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy60(&_StateBloatToken.CallOpts) } // Dummy61 is a free data retrieval call binding the contract method 0xe2d27530. // // Solidity: function dummy61() pure returns(uint256) -func (_Contract *ContractCaller) Dummy61(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy61(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy61") + err := _StateBloatToken.contract.Call(opts, &out, "dummy61") if err != nil { return *new(*big.Int), err @@ -2082,23 +2113,23 @@ func (_Contract *ContractCaller) Dummy61(opts *bind.CallOpts) (*big.Int, error) // Dummy61 is a free data retrieval call binding the contract method 0xe2d27530. // // Solidity: function dummy61() pure returns(uint256) -func (_Contract *ContractSession) Dummy61() (*big.Int, error) { - return _Contract.Contract.Dummy61(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy61() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy61(&_StateBloatToken.CallOpts) } // Dummy61 is a free data retrieval call binding the contract method 0xe2d27530. // // Solidity: function dummy61() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy61() (*big.Int, error) { - return _Contract.Contract.Dummy61(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy61() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy61(&_StateBloatToken.CallOpts) } // Dummy62 is a free data retrieval call binding the contract method 0xf5f57381. // // Solidity: function dummy62() pure returns(uint256) -func (_Contract *ContractCaller) Dummy62(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy62(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy62") + err := _StateBloatToken.contract.Call(opts, &out, "dummy62") if err != nil { return *new(*big.Int), err @@ -2113,23 +2144,23 @@ func (_Contract *ContractCaller) Dummy62(opts *bind.CallOpts) (*big.Int, error) // Dummy62 is a free data retrieval call binding the contract method 0xf5f57381. // // Solidity: function dummy62() pure returns(uint256) -func (_Contract *ContractSession) Dummy62() (*big.Int, error) { - return _Contract.Contract.Dummy62(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy62() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy62(&_StateBloatToken.CallOpts) } // Dummy62 is a free data retrieval call binding the contract method 0xf5f57381. // // Solidity: function dummy62() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy62() (*big.Int, error) { - return _Contract.Contract.Dummy62(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy62() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy62(&_StateBloatToken.CallOpts) } // Dummy63 is a free data retrieval call binding the contract method 0x7a319c18. // // Solidity: function dummy63() pure returns(uint256) -func (_Contract *ContractCaller) Dummy63(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy63(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy63") + err := _StateBloatToken.contract.Call(opts, &out, "dummy63") if err != nil { return *new(*big.Int), err @@ -2144,23 +2175,23 @@ func (_Contract *ContractCaller) Dummy63(opts *bind.CallOpts) (*big.Int, error) // Dummy63 is a free data retrieval call binding the contract method 0x7a319c18. // // Solidity: function dummy63() pure returns(uint256) -func (_Contract *ContractSession) Dummy63() (*big.Int, error) { - return _Contract.Contract.Dummy63(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy63() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy63(&_StateBloatToken.CallOpts) } // Dummy63 is a free data retrieval call binding the contract method 0x7a319c18. // // Solidity: function dummy63() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy63() (*big.Int, error) { - return _Contract.Contract.Dummy63(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy63() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy63(&_StateBloatToken.CallOpts) } // Dummy64 is a free data retrieval call binding the contract method 0xad8f4221. // // Solidity: function dummy64() pure returns(uint256) -func (_Contract *ContractCaller) Dummy64(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy64(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy64") + err := _StateBloatToken.contract.Call(opts, &out, "dummy64") if err != nil { return *new(*big.Int), err @@ -2175,23 +2206,23 @@ func (_Contract *ContractCaller) Dummy64(opts *bind.CallOpts) (*big.Int, error) // Dummy64 is a free data retrieval call binding the contract method 0xad8f4221. // // Solidity: function dummy64() pure returns(uint256) -func (_Contract *ContractSession) Dummy64() (*big.Int, error) { - return _Contract.Contract.Dummy64(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy64() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy64(&_StateBloatToken.CallOpts) } // Dummy64 is a free data retrieval call binding the contract method 0xad8f4221. // // Solidity: function dummy64() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy64() (*big.Int, error) { - return _Contract.Contract.Dummy64(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy64() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy64(&_StateBloatToken.CallOpts) } // Dummy65 is a free data retrieval call binding the contract method 0x1f449589. // // Solidity: function dummy65() pure returns(uint256) -func (_Contract *ContractCaller) Dummy65(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy65(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy65") + err := _StateBloatToken.contract.Call(opts, &out, "dummy65") if err != nil { return *new(*big.Int), err @@ -2206,23 +2237,147 @@ func (_Contract *ContractCaller) Dummy65(opts *bind.CallOpts) (*big.Int, error) // Dummy65 is a free data retrieval call binding the contract method 0x1f449589. // // Solidity: function dummy65() pure returns(uint256) -func (_Contract *ContractSession) Dummy65() (*big.Int, error) { - return _Contract.Contract.Dummy65(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy65() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy65(&_StateBloatToken.CallOpts) } // Dummy65 is a free data retrieval call binding the contract method 0x1f449589. // // Solidity: function dummy65() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy65() (*big.Int, error) { - return _Contract.Contract.Dummy65(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy65() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy65(&_StateBloatToken.CallOpts) +} + +// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. +// +// Solidity: function dummy66() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenCaller) Dummy66(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _StateBloatToken.contract.Call(opts, &out, "dummy66") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. +// +// Solidity: function dummy66() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenSession) Dummy66() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy66(&_StateBloatToken.CallOpts) +} + +// Dummy66 is a free data retrieval call binding the contract method 0xd9bb3174. +// +// Solidity: function dummy66() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy66() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy66(&_StateBloatToken.CallOpts) +} + +// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. +// +// Solidity: function dummy67() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenCaller) Dummy67(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _StateBloatToken.contract.Call(opts, &out, "dummy67") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. +// +// Solidity: function dummy67() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenSession) Dummy67() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy67(&_StateBloatToken.CallOpts) +} + +// Dummy67 is a free data retrieval call binding the contract method 0x6578534c. +// +// Solidity: function dummy67() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy67() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy67(&_StateBloatToken.CallOpts) +} + +// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. +// +// Solidity: function dummy68() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenCaller) Dummy68(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _StateBloatToken.contract.Call(opts, &out, "dummy68") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. +// +// Solidity: function dummy68() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenSession) Dummy68() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy68(&_StateBloatToken.CallOpts) +} + +// Dummy68 is a free data retrieval call binding the contract method 0xb9a6d645. +// +// Solidity: function dummy68() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy68() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy68(&_StateBloatToken.CallOpts) +} + +// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. +// +// Solidity: function dummy69() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenCaller) Dummy69(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _StateBloatToken.contract.Call(opts, &out, "dummy69") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. +// +// Solidity: function dummy69() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenSession) Dummy69() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy69(&_StateBloatToken.CallOpts) +} + +// Dummy69 is a free data retrieval call binding the contract method 0x2787325b. +// +// Solidity: function dummy69() pure returns(uint256) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy69() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy69(&_StateBloatToken.CallOpts) } // Dummy7 is a free data retrieval call binding the contract method 0xf26c779b. // // Solidity: function dummy7() pure returns(uint256) -func (_Contract *ContractCaller) Dummy7(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy7(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy7") + err := _StateBloatToken.contract.Call(opts, &out, "dummy7") if err != nil { return *new(*big.Int), err @@ -2237,23 +2392,23 @@ func (_Contract *ContractCaller) Dummy7(opts *bind.CallOpts) (*big.Int, error) { // Dummy7 is a free data retrieval call binding the contract method 0xf26c779b. // // Solidity: function dummy7() pure returns(uint256) -func (_Contract *ContractSession) Dummy7() (*big.Int, error) { - return _Contract.Contract.Dummy7(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy7() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy7(&_StateBloatToken.CallOpts) } // Dummy7 is a free data retrieval call binding the contract method 0xf26c779b. // // Solidity: function dummy7() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy7() (*big.Int, error) { - return _Contract.Contract.Dummy7(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy7() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy7(&_StateBloatToken.CallOpts) } // Dummy8 is a free data retrieval call binding the contract method 0x19cf6a91. // // Solidity: function dummy8() pure returns(uint256) -func (_Contract *ContractCaller) Dummy8(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy8(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy8") + err := _StateBloatToken.contract.Call(opts, &out, "dummy8") if err != nil { return *new(*big.Int), err @@ -2268,23 +2423,23 @@ func (_Contract *ContractCaller) Dummy8(opts *bind.CallOpts) (*big.Int, error) { // Dummy8 is a free data retrieval call binding the contract method 0x19cf6a91. // // Solidity: function dummy8() pure returns(uint256) -func (_Contract *ContractSession) Dummy8() (*big.Int, error) { - return _Contract.Contract.Dummy8(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy8() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy8(&_StateBloatToken.CallOpts) } // Dummy8 is a free data retrieval call binding the contract method 0x19cf6a91. // // Solidity: function dummy8() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy8() (*big.Int, error) { - return _Contract.Contract.Dummy8(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy8() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy8(&_StateBloatToken.CallOpts) } // Dummy9 is a free data retrieval call binding the contract method 0x58b6a9bd. // // Solidity: function dummy9() pure returns(uint256) -func (_Contract *ContractCaller) Dummy9(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Dummy9(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "dummy9") + err := _StateBloatToken.contract.Call(opts, &out, "dummy9") if err != nil { return *new(*big.Int), err @@ -2299,23 +2454,23 @@ func (_Contract *ContractCaller) Dummy9(opts *bind.CallOpts) (*big.Int, error) { // Dummy9 is a free data retrieval call binding the contract method 0x58b6a9bd. // // Solidity: function dummy9() pure returns(uint256) -func (_Contract *ContractSession) Dummy9() (*big.Int, error) { - return _Contract.Contract.Dummy9(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Dummy9() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy9(&_StateBloatToken.CallOpts) } // Dummy9 is a free data retrieval call binding the contract method 0x58b6a9bd. // // Solidity: function dummy9() pure returns(uint256) -func (_Contract *ContractCallerSession) Dummy9() (*big.Int, error) { - return _Contract.Contract.Dummy9(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Dummy9() (*big.Int, error) { + return _StateBloatToken.Contract.Dummy9(&_StateBloatToken.CallOpts) } // Name is a free data retrieval call binding the contract method 0x06fdde03. // // Solidity: function name() view returns(string) -func (_Contract *ContractCaller) Name(opts *bind.CallOpts) (string, error) { +func (_StateBloatToken *StateBloatTokenCaller) Name(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "name") + err := _StateBloatToken.contract.Call(opts, &out, "name") if err != nil { return *new(string), err @@ -2330,23 +2485,23 @@ func (_Contract *ContractCaller) Name(opts *bind.CallOpts) (string, error) { // Name is a free data retrieval call binding the contract method 0x06fdde03. // // Solidity: function name() view returns(string) -func (_Contract *ContractSession) Name() (string, error) { - return _Contract.Contract.Name(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Name() (string, error) { + return _StateBloatToken.Contract.Name(&_StateBloatToken.CallOpts) } // Name is a free data retrieval call binding the contract method 0x06fdde03. // // Solidity: function name() view returns(string) -func (_Contract *ContractCallerSession) Name() (string, error) { - return _Contract.Contract.Name(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Name() (string, error) { + return _StateBloatToken.Contract.Name(&_StateBloatToken.CallOpts) } // Salt is a free data retrieval call binding the contract method 0xbfa0b133. // // Solidity: function salt() view returns(uint256) -func (_Contract *ContractCaller) Salt(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) Salt(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "salt") + err := _StateBloatToken.contract.Call(opts, &out, "salt") if err != nil { return *new(*big.Int), err @@ -2361,23 +2516,23 @@ func (_Contract *ContractCaller) Salt(opts *bind.CallOpts) (*big.Int, error) { // Salt is a free data retrieval call binding the contract method 0xbfa0b133. // // Solidity: function salt() view returns(uint256) -func (_Contract *ContractSession) Salt() (*big.Int, error) { - return _Contract.Contract.Salt(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Salt() (*big.Int, error) { + return _StateBloatToken.Contract.Salt(&_StateBloatToken.CallOpts) } // Salt is a free data retrieval call binding the contract method 0xbfa0b133. // // Solidity: function salt() view returns(uint256) -func (_Contract *ContractCallerSession) Salt() (*big.Int, error) { - return _Contract.Contract.Salt(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Salt() (*big.Int, error) { + return _StateBloatToken.Contract.Salt(&_StateBloatToken.CallOpts) } // Symbol is a free data retrieval call binding the contract method 0x95d89b41. // // Solidity: function symbol() view returns(string) -func (_Contract *ContractCaller) Symbol(opts *bind.CallOpts) (string, error) { +func (_StateBloatToken *StateBloatTokenCaller) Symbol(opts *bind.CallOpts) (string, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "symbol") + err := _StateBloatToken.contract.Call(opts, &out, "symbol") if err != nil { return *new(string), err @@ -2392,23 +2547,23 @@ func (_Contract *ContractCaller) Symbol(opts *bind.CallOpts) (string, error) { // Symbol is a free data retrieval call binding the contract method 0x95d89b41. // // Solidity: function symbol() view returns(string) -func (_Contract *ContractSession) Symbol() (string, error) { - return _Contract.Contract.Symbol(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) Symbol() (string, error) { + return _StateBloatToken.Contract.Symbol(&_StateBloatToken.CallOpts) } // Symbol is a free data retrieval call binding the contract method 0x95d89b41. // // Solidity: function symbol() view returns(string) -func (_Contract *ContractCallerSession) Symbol() (string, error) { - return _Contract.Contract.Symbol(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) Symbol() (string, error) { + return _StateBloatToken.Contract.Symbol(&_StateBloatToken.CallOpts) } // TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. // // Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { +func (_StateBloatToken *StateBloatTokenCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "totalSupply") + err := _StateBloatToken.contract.Call(opts, &out, "totalSupply") if err != nil { return *new(*big.Int), err @@ -2423,482 +2578,482 @@ func (_Contract *ContractCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, err // TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. // // Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractSession) TotalSupply() (*big.Int, error) { - return _Contract.Contract.TotalSupply(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenSession) TotalSupply() (*big.Int, error) { + return _StateBloatToken.Contract.TotalSupply(&_StateBloatToken.CallOpts) } // TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. // // Solidity: function totalSupply() view returns(uint256) -func (_Contract *ContractCallerSession) TotalSupply() (*big.Int, error) { - return _Contract.Contract.TotalSupply(&_Contract.CallOpts) +func (_StateBloatToken *StateBloatTokenCallerSession) TotalSupply() (*big.Int, error) { + return _StateBloatToken.Contract.TotalSupply(&_StateBloatToken.CallOpts) } // Approve is a paid mutator transaction binding the contract method 0x095ea7b3. // // Solidity: function approve(address spender, uint256 value) returns(bool) -func (_Contract *ContractTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "approve", spender, value) +func (_StateBloatToken *StateBloatTokenTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "approve", spender, value) } // Approve is a paid mutator transaction binding the contract method 0x095ea7b3. // // Solidity: function approve(address spender, uint256 value) returns(bool) -func (_Contract *ContractSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Approve(&_Contract.TransactOpts, spender, value) +func (_StateBloatToken *StateBloatTokenSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.Approve(&_StateBloatToken.TransactOpts, spender, value) } // Approve is a paid mutator transaction binding the contract method 0x095ea7b3. // // Solidity: function approve(address spender, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Approve(&_Contract.TransactOpts, spender, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.Approve(&_StateBloatToken.TransactOpts, spender, value) } // Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. // // Solidity: function transfer(address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transfer", to, value) +func (_StateBloatToken *StateBloatTokenTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transfer", to, value) } // Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. // // Solidity: function transfer(address to, uint256 value) returns(bool) -func (_Contract *ContractSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Transfer(&_Contract.TransactOpts, to, value) +func (_StateBloatToken *StateBloatTokenSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.Transfer(&_StateBloatToken.TransactOpts, to, value) } // Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. // // Solidity: function transfer(address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.Transfer(&_Contract.TransactOpts, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.Transfer(&_StateBloatToken.TransactOpts, to, value) } // TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. // // Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom", from, to, value) } // TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. // // Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. // // Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom1 is a paid mutator transaction binding the contract method 0xbb9bfe06. // // Solidity: function transferFrom1(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom1(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom1", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom1(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom1", from, to, value) } // TransferFrom1 is a paid mutator transaction binding the contract method 0xbb9bfe06. // // Solidity: function transferFrom1(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom1(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom1(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom1(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom1(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom1 is a paid mutator transaction binding the contract method 0xbb9bfe06. // // Solidity: function transferFrom1(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom1(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom1(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom1(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom1(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom10 is a paid mutator transaction binding the contract method 0xb1802b9a. // // Solidity: function transferFrom10(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom10(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom10", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom10(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom10", from, to, value) } // TransferFrom10 is a paid mutator transaction binding the contract method 0xb1802b9a. // // Solidity: function transferFrom10(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom10(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom10(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom10(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom10(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom10 is a paid mutator transaction binding the contract method 0xb1802b9a. // // Solidity: function transferFrom10(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom10(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom10(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom10(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom10(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom11 is a paid mutator transaction binding the contract method 0xc2be97e3. // // Solidity: function transferFrom11(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom11(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom11", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom11(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom11", from, to, value) } // TransferFrom11 is a paid mutator transaction binding the contract method 0xc2be97e3. // // Solidity: function transferFrom11(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom11(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom11(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom11(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom11(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom11 is a paid mutator transaction binding the contract method 0xc2be97e3. // // Solidity: function transferFrom11(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom11(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom11(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom11(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom11(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom12 is a paid mutator transaction binding the contract method 0x44050a28. // // Solidity: function transferFrom12(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom12(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom12", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom12(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom12", from, to, value) } // TransferFrom12 is a paid mutator transaction binding the contract method 0x44050a28. // // Solidity: function transferFrom12(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom12(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom12(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom12(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom12(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom12 is a paid mutator transaction binding the contract method 0x44050a28. // // Solidity: function transferFrom12(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom12(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom12(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom12(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom12(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom13 is a paid mutator transaction binding the contract method 0xacc5aee9. // // Solidity: function transferFrom13(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom13(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom13", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom13(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom13", from, to, value) } // TransferFrom13 is a paid mutator transaction binding the contract method 0xacc5aee9. // // Solidity: function transferFrom13(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom13(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom13(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom13(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom13(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom13 is a paid mutator transaction binding the contract method 0xacc5aee9. // // Solidity: function transferFrom13(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom13(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom13(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom13(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom13(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom14 is a paid mutator transaction binding the contract method 0x1bbffe6f. // // Solidity: function transferFrom14(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom14(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom14", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom14(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom14", from, to, value) } // TransferFrom14 is a paid mutator transaction binding the contract method 0x1bbffe6f. // // Solidity: function transferFrom14(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom14(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom14(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom14(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom14(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom14 is a paid mutator transaction binding the contract method 0x1bbffe6f. // // Solidity: function transferFrom14(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom14(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom14(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom14(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom14(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom15 is a paid mutator transaction binding the contract method 0x8789ca67. // // Solidity: function transferFrom15(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom15(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom15", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom15(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom15", from, to, value) } // TransferFrom15 is a paid mutator transaction binding the contract method 0x8789ca67. // // Solidity: function transferFrom15(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom15(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom15(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom15(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom15(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom15 is a paid mutator transaction binding the contract method 0x8789ca67. // // Solidity: function transferFrom15(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom15(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom15(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom15(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom15(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom16 is a paid mutator transaction binding the contract method 0x39e0bd12. // // Solidity: function transferFrom16(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom16(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom16", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom16(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom16", from, to, value) } // TransferFrom16 is a paid mutator transaction binding the contract method 0x39e0bd12. // // Solidity: function transferFrom16(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom16(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom16(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom16(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom16(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom16 is a paid mutator transaction binding the contract method 0x39e0bd12. // // Solidity: function transferFrom16(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom16(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom16(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom16(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom16(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom17 is a paid mutator transaction binding the contract method 0x291c3bd7. // // Solidity: function transferFrom17(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom17(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom17", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom17(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom17", from, to, value) } // TransferFrom17 is a paid mutator transaction binding the contract method 0x291c3bd7. // // Solidity: function transferFrom17(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom17(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom17(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom17(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom17(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom17 is a paid mutator transaction binding the contract method 0x291c3bd7. // // Solidity: function transferFrom17(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom17(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom17(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom17(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom17(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom18 is a paid mutator transaction binding the contract method 0x657b6ef7. // // Solidity: function transferFrom18(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom18(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom18", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom18(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom18", from, to, value) } // TransferFrom18 is a paid mutator transaction binding the contract method 0x657b6ef7. // // Solidity: function transferFrom18(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom18(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom18(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom18(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom18(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom18 is a paid mutator transaction binding the contract method 0x657b6ef7. // // Solidity: function transferFrom18(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom18(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom18(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom18(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom18(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom19 is a paid mutator transaction binding the contract method 0xeb4329c8. // // Solidity: function transferFrom19(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom19(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom19", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom19(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom19", from, to, value) } // TransferFrom19 is a paid mutator transaction binding the contract method 0xeb4329c8. // // Solidity: function transferFrom19(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom19(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom19(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom19(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom19(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom19 is a paid mutator transaction binding the contract method 0xeb4329c8. // // Solidity: function transferFrom19(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom19(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom19(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom19(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom19(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom2 is a paid mutator transaction binding the contract method 0x6c12ed28. // // Solidity: function transferFrom2(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom2(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom2", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom2(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom2", from, to, value) } // TransferFrom2 is a paid mutator transaction binding the contract method 0x6c12ed28. // // Solidity: function transferFrom2(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom2(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom2(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom2(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom2(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom2 is a paid mutator transaction binding the contract method 0x6c12ed28. // // Solidity: function transferFrom2(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom2(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom2(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom2(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom2(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom3 is a paid mutator transaction binding the contract method 0x1b17c65c. // // Solidity: function transferFrom3(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom3(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom3", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom3(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom3", from, to, value) } // TransferFrom3 is a paid mutator transaction binding the contract method 0x1b17c65c. // // Solidity: function transferFrom3(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom3(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom3(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom3(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom3(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom3 is a paid mutator transaction binding the contract method 0x1b17c65c. // // Solidity: function transferFrom3(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom3(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom3(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom3(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom3(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom4 is a paid mutator transaction binding the contract method 0x3a131990. // // Solidity: function transferFrom4(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom4(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom4", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom4(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom4", from, to, value) } // TransferFrom4 is a paid mutator transaction binding the contract method 0x3a131990. // // Solidity: function transferFrom4(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom4(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom4(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom4(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom4(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom4 is a paid mutator transaction binding the contract method 0x3a131990. // // Solidity: function transferFrom4(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom4(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom4(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom4(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom4(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom5 is a paid mutator transaction binding the contract method 0x0460faf6. // // Solidity: function transferFrom5(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom5(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom5", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom5(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom5", from, to, value) } // TransferFrom5 is a paid mutator transaction binding the contract method 0x0460faf6. // // Solidity: function transferFrom5(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom5(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom5(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom5(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom5(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom5 is a paid mutator transaction binding the contract method 0x0460faf6. // // Solidity: function transferFrom5(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom5(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom5(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom5(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom5(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom6 is a paid mutator transaction binding the contract method 0x7c66673e. // // Solidity: function transferFrom6(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom6(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom6", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom6(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom6", from, to, value) } // TransferFrom6 is a paid mutator transaction binding the contract method 0x7c66673e. // // Solidity: function transferFrom6(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom6(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom6(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom6(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom6(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom6 is a paid mutator transaction binding the contract method 0x7c66673e. // // Solidity: function transferFrom6(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom6(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom6(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom6(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom6(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom7 is a paid mutator transaction binding the contract method 0xfaf35ced. // // Solidity: function transferFrom7(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom7(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom7", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom7(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom7", from, to, value) } // TransferFrom7 is a paid mutator transaction binding the contract method 0xfaf35ced. // // Solidity: function transferFrom7(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom7(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom7(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom7(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom7(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom7 is a paid mutator transaction binding the contract method 0xfaf35ced. // // Solidity: function transferFrom7(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom7(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom7(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom7(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom7(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom8 is a paid mutator transaction binding the contract method 0x552a1b56. // // Solidity: function transferFrom8(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom8(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom8", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom8(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom8", from, to, value) } // TransferFrom8 is a paid mutator transaction binding the contract method 0x552a1b56. // // Solidity: function transferFrom8(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom8(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom8(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom8(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom8(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom8 is a paid mutator transaction binding the contract method 0x552a1b56. // // Solidity: function transferFrom8(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom8(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom8(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom8(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom8(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom9 is a paid mutator transaction binding the contract method 0x4f7bd75a. // // Solidity: function transferFrom9(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactor) TransferFrom9(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.contract.Transact(opts, "transferFrom9", from, to, value) +func (_StateBloatToken *StateBloatTokenTransactor) TransferFrom9(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.contract.Transact(opts, "transferFrom9", from, to, value) } // TransferFrom9 is a paid mutator transaction binding the contract method 0x4f7bd75a. // // Solidity: function transferFrom9(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractSession) TransferFrom9(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom9(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenSession) TransferFrom9(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom9(&_StateBloatToken.TransactOpts, from, to, value) } // TransferFrom9 is a paid mutator transaction binding the contract method 0x4f7bd75a. // // Solidity: function transferFrom9(address from, address to, uint256 value) returns(bool) -func (_Contract *ContractTransactorSession) TransferFrom9(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { - return _Contract.Contract.TransferFrom9(&_Contract.TransactOpts, from, to, value) +func (_StateBloatToken *StateBloatTokenTransactorSession) TransferFrom9(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _StateBloatToken.Contract.TransferFrom9(&_StateBloatToken.TransactOpts, from, to, value) } -// ContractApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the Contract contract. -type ContractApprovalIterator struct { - Event *ContractApproval // Event containing the contract specifics and raw log +// StateBloatTokenApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the StateBloatToken contract. +type StateBloatTokenApprovalIterator struct { + Event *StateBloatTokenApproval // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2912,7 +3067,7 @@ type ContractApprovalIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ContractApprovalIterator) Next() bool { +func (it *StateBloatTokenApprovalIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2921,7 +3076,7 @@ func (it *ContractApprovalIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ContractApproval) + it.Event = new(StateBloatTokenApproval) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2936,7 +3091,7 @@ func (it *ContractApprovalIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ContractApproval) + it.Event = new(StateBloatTokenApproval) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2952,19 +3107,19 @@ func (it *ContractApprovalIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractApprovalIterator) Error() error { +func (it *StateBloatTokenApprovalIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ContractApprovalIterator) Close() error { +func (it *StateBloatTokenApprovalIterator) Close() error { it.sub.Unsubscribe() return nil } -// ContractApproval represents a Approval event raised by the Contract contract. -type ContractApproval struct { +// StateBloatTokenApproval represents a Approval event raised by the StateBloatToken contract. +type StateBloatTokenApproval struct { Owner common.Address Spender common.Address Value *big.Int @@ -2974,7 +3129,7 @@ type ContractApproval struct { // FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. // // Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) -func (_Contract *ContractFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ContractApprovalIterator, error) { +func (_StateBloatToken *StateBloatTokenFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*StateBloatTokenApprovalIterator, error) { var ownerRule []interface{} for _, ownerItem := range owner { @@ -2985,17 +3140,17 @@ func (_Contract *ContractFilterer) FilterApproval(opts *bind.FilterOpts, owner [ spenderRule = append(spenderRule, spenderItem) } - logs, sub, err := _Contract.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + logs, sub, err := _StateBloatToken.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) if err != nil { return nil, err } - return &ContractApprovalIterator{contract: _Contract.contract, event: "Approval", logs: logs, sub: sub}, nil + return &StateBloatTokenApprovalIterator{contract: _StateBloatToken.contract, event: "Approval", logs: logs, sub: sub}, nil } // WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. // // Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) -func (_Contract *ContractFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ContractApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { +func (_StateBloatToken *StateBloatTokenFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *StateBloatTokenApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { var ownerRule []interface{} for _, ownerItem := range owner { @@ -3006,7 +3161,7 @@ func (_Contract *ContractFilterer) WatchApproval(opts *bind.WatchOpts, sink chan spenderRule = append(spenderRule, spenderItem) } - logs, sub, err := _Contract.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + logs, sub, err := _StateBloatToken.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) if err != nil { return nil, err } @@ -3016,8 +3171,8 @@ func (_Contract *ContractFilterer) WatchApproval(opts *bind.WatchOpts, sink chan select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ContractApproval) - if err := _Contract.contract.UnpackLog(event, "Approval", log); err != nil { + event := new(StateBloatTokenApproval) + if err := _StateBloatToken.contract.UnpackLog(event, "Approval", log); err != nil { return err } event.Raw = log @@ -3041,18 +3196,18 @@ func (_Contract *ContractFilterer) WatchApproval(opts *bind.WatchOpts, sink chan // ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. // // Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) -func (_Contract *ContractFilterer) ParseApproval(log types.Log) (*ContractApproval, error) { - event := new(ContractApproval) - if err := _Contract.contract.UnpackLog(event, "Approval", log); err != nil { +func (_StateBloatToken *StateBloatTokenFilterer) ParseApproval(log types.Log) (*StateBloatTokenApproval, error) { + event := new(StateBloatTokenApproval) + if err := _StateBloatToken.contract.UnpackLog(event, "Approval", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ContractTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the Contract contract. -type ContractTransferIterator struct { - Event *ContractTransfer // Event containing the contract specifics and raw log +// StateBloatTokenTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the StateBloatToken contract. +type StateBloatTokenTransferIterator struct { + Event *StateBloatTokenTransfer // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -3066,7 +3221,7 @@ type ContractTransferIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ContractTransferIterator) Next() bool { +func (it *StateBloatTokenTransferIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -3075,7 +3230,7 @@ func (it *ContractTransferIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ContractTransfer) + it.Event = new(StateBloatTokenTransfer) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3090,7 +3245,7 @@ func (it *ContractTransferIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ContractTransfer) + it.Event = new(StateBloatTokenTransfer) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3106,19 +3261,19 @@ func (it *ContractTransferIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ContractTransferIterator) Error() error { +func (it *StateBloatTokenTransferIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ContractTransferIterator) Close() error { +func (it *StateBloatTokenTransferIterator) Close() error { it.sub.Unsubscribe() return nil } -// ContractTransfer represents a Transfer event raised by the Contract contract. -type ContractTransfer struct { +// StateBloatTokenTransfer represents a Transfer event raised by the StateBloatToken contract. +type StateBloatTokenTransfer struct { From common.Address To common.Address Value *big.Int @@ -3128,7 +3283,7 @@ type ContractTransfer struct { // FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. // // Solidity: event Transfer(address indexed from, address indexed to, uint256 value) -func (_Contract *ContractFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ContractTransferIterator, error) { +func (_StateBloatToken *StateBloatTokenFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*StateBloatTokenTransferIterator, error) { var fromRule []interface{} for _, fromItem := range from { @@ -3139,17 +3294,17 @@ func (_Contract *ContractFilterer) FilterTransfer(opts *bind.FilterOpts, from [] toRule = append(toRule, toItem) } - logs, sub, err := _Contract.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + logs, sub, err := _StateBloatToken.contract.FilterLogs(opts, "Transfer", fromRule, toRule) if err != nil { return nil, err } - return &ContractTransferIterator{contract: _Contract.contract, event: "Transfer", logs: logs, sub: sub}, nil + return &StateBloatTokenTransferIterator{contract: _StateBloatToken.contract, event: "Transfer", logs: logs, sub: sub}, nil } // WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. // // Solidity: event Transfer(address indexed from, address indexed to, uint256 value) -func (_Contract *ContractFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ContractTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { +func (_StateBloatToken *StateBloatTokenFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *StateBloatTokenTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { var fromRule []interface{} for _, fromItem := range from { @@ -3160,7 +3315,7 @@ func (_Contract *ContractFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan toRule = append(toRule, toItem) } - logs, sub, err := _Contract.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + logs, sub, err := _StateBloatToken.contract.WatchLogs(opts, "Transfer", fromRule, toRule) if err != nil { return nil, err } @@ -3170,8 +3325,8 @@ func (_Contract *ContractFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ContractTransfer) - if err := _Contract.contract.UnpackLog(event, "Transfer", log); err != nil { + event := new(StateBloatTokenTransfer) + if err := _StateBloatToken.contract.UnpackLog(event, "Transfer", log); err != nil { return err } event.Raw = log @@ -3195,9 +3350,9 @@ func (_Contract *ContractFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan // ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. // // Solidity: event Transfer(address indexed from, address indexed to, uint256 value) -func (_Contract *ContractFilterer) ParseTransfer(log types.Log) (*ContractTransfer, error) { - event := new(ContractTransfer) - if err := _Contract.contract.UnpackLog(event, "Transfer", log); err != nil { +func (_StateBloatToken *StateBloatTokenFilterer) ParseTransfer(log types.Log) (*StateBloatTokenTransfer, error) { + event := new(StateBloatTokenTransfer) + if err := _StateBloatToken.contract.UnpackLog(event, "Transfer", log); err != nil { return nil, err } event.Raw = log diff --git a/scenarios/statebloat/contract_deploy/contract/compile.sh b/scenarios/statebloat/contract_deploy/contract/compile.sh new file mode 100755 index 00000000..c96a3f4f --- /dev/null +++ b/scenarios/statebloat/contract_deploy/contract/compile.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +compile_contract() { + local workdir=$1 + local solc_version=$2 + local solc_args=$3 + local contract_file=$4 + local contract_name=$5 + + if [ -z "$contract_name" ]; then + contract_name="$contract_file" + fi + + #echo "docker run --rm -v $workdir:/contracts ethereum/solc:$solc_version /contracts/$contract_file.sol --combined-json abi,bin $solc_args" + local contract_json=$(docker run --rm -v $workdir:/contracts ethereum/solc:$solc_version /contracts/$contract_file.sol --combined-json abi,bin $solc_args) + + local contract_abi=$(echo "$contract_json" | jq -r '.contracts["/contracts/'$contract_file'.sol:'$contract_name'"].abi') + if [ "$contract_abi" == "null" ]; then + contract_abi=$(echo "$contract_json" | jq -r '.contracts["contracts/'$contract_file'.sol:'$contract_name'"].abi') + fi + + local contract_bin=$(echo "$contract_json" | jq -r '.contracts["/contracts/'$contract_file'.sol:'$contract_name'"].bin') + if [ "$contract_bin" == "null" ]; then + contract_bin=$(echo "$contract_json" | jq -r '.contracts["contracts/'$contract_file'.sol:'$contract_name'"].bin') + fi + + echo "$contract_abi" > $contract_name.abi + echo "$contract_bin" > $contract_name.bin + abigen --bin=./$contract_name.bin --abi=./$contract_name.abi --pkg=contract --out=$contract_name.go --type $contract_name + rm $contract_name.bin $contract_name.abi + echo "$contract_json" | jq > $contract_name.output.json +} + +# StateBloatToken +compile_contract "$(pwd)" 0.8.22 "--optimize --optimize-runs 999999" StateBloatToken diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index d2018956..220f23bb 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -1,4 +1,4 @@ -package contractdeploy +package sbcontractdeploy import ( "context" @@ -18,13 +18,15 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/holiman/uint256" "github.com/sirupsen/logrus" "github.com/spf13/pflag" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethpandaops/spamoor/scenario" "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy/contract" - "github.com/ethpandaops/spamoor/scenariotypes" "github.com/ethpandaops/spamoor/spamoor" + "github.com/ethpandaops/spamoor/txbuilder" ) type ScenarioOptions struct { @@ -42,13 +44,6 @@ type ContractDeployment struct { PrivateKey string `json:"private_key"` } -// PendingTransaction tracks a transaction until it's mined -type PendingTransaction struct { - TxHash common.Hash - PrivateKey *ecdsa.PrivateKey - Timestamp time.Time -} - // BlockDeploymentStats tracks deployment statistics per block type BlockDeploymentStats struct { BlockNumber uint64 @@ -62,15 +57,6 @@ type Scenario struct { logger *logrus.Entry walletPool *spamoor.WalletPool - // Cached chain ID to avoid repeated RPC calls - chainID *big.Int - chainIDOnce sync.Once - chainIDError error - - // Transaction tracking - pendingTxs map[common.Hash]*PendingTransaction - pendingTxsMutex sync.RWMutex - // Results tracking deployedContracts []ContractDeployment contractsMutex sync.Mutex @@ -79,30 +65,25 @@ type Scenario struct { blockStats map[uint64]*BlockDeploymentStats blockStatsMutex sync.Mutex lastLoggedBlock uint64 - - // Block monitoring for real-time logging - blockMonitorCancel context.CancelFunc - blockMonitorDone chan struct{} } -var ScenarioName = "contract-deploy" +var ScenarioName = "statebloat-contract-deploy" var ScenarioDefaultOptions = ScenarioOptions{ MaxWallets: 0, // Use root wallet only by default BaseFee: 5, // Moderate base fee (5 gwei) TipFee: 1, // Priority fee (1 gwei) MaxTransactions: 0, } -var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ +var ScenarioDescriptor = scenario.Descriptor{ Name: ScenarioName, Description: "Deploy contracts to create state bloat", DefaultOptions: ScenarioDefaultOptions, NewScenario: newScenario, } -func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { +func newScenario(logger logrus.FieldLogger) scenario.Scenario { return &Scenario{ - logger: logger.WithField("scenario", ScenarioName), - pendingTxs: make(map[common.Hash]*PendingTransaction), + logger: logger.WithField("scenario", ScenarioName), } } @@ -116,132 +97,25 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { return nil } -func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { - s.walletPool = walletPool +func (s *Scenario) Init(options *scenario.Options) error { + s.walletPool = options.WalletPool - if config != "" { - err := yaml.Unmarshal([]byte(config), &s.options) + if options.Config != "" { + err := yaml.Unmarshal([]byte(options.Config), &s.options) if err != nil { return fmt.Errorf("failed to unmarshal config: %w", err) } } if s.options.MaxWallets > 0 { - walletPool.SetWalletCount(s.options.MaxWallets) + s.walletPool.SetWalletCount(s.options.MaxWallets) } else { - // Use only root wallet by default for better efficiency - // This avoids child wallet funding overhead - walletPool.SetWalletCount(0) + s.walletPool.SetWalletCount(10) } return nil } -func (s *Scenario) Config() string { - yamlBytes, _ := yaml.Marshal(&s.options) - return string(yamlBytes) -} - -// getChainID caches the chain ID to avoid repeated RPC calls -func (s *Scenario) getChainID(ctx context.Context) (*big.Int, error) { - s.chainIDOnce.Do(func() { - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) - if client == nil { - s.chainIDError = fmt.Errorf("no client available for chain ID") - return - } - s.chainID, s.chainIDError = client.GetChainId(ctx) - }) - return s.chainID, s.chainIDError -} - -// waitForPendingTxSlot waits until we have capacity for another transaction -func (s *Scenario) waitForPendingTxSlot(ctx context.Context) { - for { - s.pendingTxsMutex.RLock() - count := len(s.pendingTxs) - s.pendingTxsMutex.RUnlock() - - if count < int(s.options.MaxPending) { - return - } - - // Check and clean up confirmed transactions - s.processPendingTransactions(ctx) - time.Sleep(1 * time.Second) - } -} - -// processPendingTransactions checks for transaction confirmations and updates state -func (s *Scenario) processPendingTransactions(ctx context.Context) { - s.pendingTxsMutex.Lock() - - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) - if client == nil { - s.pendingTxsMutex.Unlock() - return - } - - ethClient := client.GetEthClient() - var confirmedTxs []common.Hash - var timedOutTxs []common.Hash - var successfulDeployments []struct { - ContractAddress common.Address - PrivateKey *ecdsa.PrivateKey - Receipt *types.Receipt - TxHash common.Hash - } - - for txHash, pendingTx := range s.pendingTxs { - // Check if transaction is too old (1 minute timeout) - if time.Since(pendingTx.Timestamp) > 1*time.Minute { - s.logger.Warnf("Transaction %s timed out after 1 minute, removing from pending", txHash.Hex()) - timedOutTxs = append(timedOutTxs, txHash) - continue - } - - receipt, err := ethClient.TransactionReceipt(ctx, txHash) - if err != nil { - // Transaction still pending or error retrieving receipt - continue - } - - confirmedTxs = append(confirmedTxs, txHash) - - // Process successful deployment - if receipt.Status == 1 && receipt.ContractAddress != (common.Address{}) { - successfulDeployments = append(successfulDeployments, struct { - ContractAddress common.Address - PrivateKey *ecdsa.PrivateKey - Receipt *types.Receipt - TxHash common.Hash - }{ - ContractAddress: receipt.ContractAddress, - PrivateKey: pendingTx.PrivateKey, - Receipt: receipt, - TxHash: txHash, - }) - } - } - - // Remove confirmed transactions from pending map - for _, txHash := range confirmedTxs { - delete(s.pendingTxs, txHash) - } - - // Remove timed out transactions from pending map - for _, txHash := range timedOutTxs { - delete(s.pendingTxs, txHash) - } - - s.pendingTxsMutex.Unlock() - - // Process successful deployments after releasing the lock - for _, deployment := range successfulDeployments { - s.recordDeployedContract(deployment.ContractAddress, deployment.PrivateKey, deployment.Receipt, deployment.TxHash) - } -} - // recordDeployedContract records a successfully deployed contract func (s *Scenario) recordDeployedContract(contractAddress common.Address, privateKey *ecdsa.PrivateKey, receipt *types.Receipt, txHash common.Hash) { s.contractsMutex.Lock() @@ -350,13 +224,7 @@ func (s *Scenario) saveDeploymentsMapping() error { // startBlockMonitor starts a background goroutine that monitors for new blocks // and logs block deployment summaries immediately when blocks are mined func (s *Scenario) startBlockMonitor(ctx context.Context) { - monitorCtx, cancel := context.WithCancel(ctx) - s.blockMonitorCancel = cancel - s.blockMonitorDone = make(chan struct{}) - go func() { - defer close(s.blockMonitorDone) - client := s.walletPool.GetClient(spamoor.SelectClientByIndex, 0, s.options.ClientGroup) if client == nil { s.logger.Warn("No client available for block monitoring") @@ -369,11 +237,11 @@ func (s *Scenario) startBlockMonitor(ctx context.Context) { for { select { - case <-monitorCtx.Done(): + case <-ctx.Done(): return case <-ticker.C: // Get current block number - latestBlock, err := ethClient.BlockByNumber(monitorCtx, nil) + latestBlock, err := ethClient.BlockByNumber(ctx, nil) if err != nil { s.logger.WithError(err).Debug("Failed to get latest block for monitoring") continue @@ -409,35 +277,17 @@ func (s *Scenario) startBlockMonitor(ctx context.Context) { }() } -// stopBlockMonitor stops the block monitoring goroutine -func (s *Scenario) stopBlockMonitor() { - if s.blockMonitorCancel != nil { - s.blockMonitorCancel() - } - if s.blockMonitorDone != nil { - <-s.blockMonitorDone // Wait for goroutine to finish - } -} - func (s *Scenario) Run(ctx context.Context) error { s.logger.Infof("starting scenario: %s", ScenarioName) defer s.logger.Infof("scenario %s finished.", ScenarioName) // Start block monitoring for real-time logging s.startBlockMonitor(ctx) - defer s.stopBlockMonitor() - - // Cache chain ID at startup - chainID, err := s.getChainID(ctx) - if err != nil { - return fmt.Errorf("failed to get chain ID: %w", err) - } - - s.logger.Infof("Chain ID: %s", chainID.String()) // Calculate rate limiting based on block gas limit if max-transactions is 0 var maxTxsPerBlock uint64 - var useRateLimiting bool + var maxPending uint64 = 100 + var totalTxCount uint64 = 0 if s.options.MaxTransactions == 0 { // Get block gas limit from the network @@ -455,88 +305,37 @@ func (s *Scenario) Run(ctx context.Context) error { // TODO: This should be a constant. estimatedGasPerContract := uint64(4949468) // Updated estimate based on contract size reduction maxTxsPerBlock = blockGasLimit / estimatedGasPerContract - useRateLimiting = true s.logger.Infof("Rate limiting enabled: block gas limit %d, gas per contract %d, max txs per block %d", blockGasLimit, estimatedGasPerContract, maxTxsPerBlock) } - txIdxCounter := uint64(0) - totalTxCount := atomic.Uint64{} - blockTxCount := uint64(0) - lastBlockTime := time.Now() - - for { - // Check if we've reached max transactions (if set) - if s.options.MaxTransactions > 0 && txIdxCounter >= s.options.MaxTransactions { - s.logger.Infof("reached maximum number of transactions (%d)", s.options.MaxTransactions) - break - } - - // Rate limiting logic - if useRateLimiting { - // If we've sent maxTxsPerBlock transactions, wait for next block interval - if blockTxCount >= maxTxsPerBlock { - timeSinceLastBlock := time.Since(lastBlockTime) - if timeSinceLastBlock < 12*time.Second { // Assume ~12 second block time - sleepTime := 12*time.Second - timeSinceLastBlock - s.logger.Infof("Rate limit reached (%d txs), waiting %v for next block", maxTxsPerBlock, sleepTime) - time.Sleep(sleepTime) - } - blockTxCount = 0 - lastBlockTime = time.Now() - } - } - - // Wait for available slot - s.waitForPendingTxSlot(ctx) - - // Send a single transaction - err := s.sendTransaction(ctx, txIdxCounter) - if err != nil { - s.logger.Warnf("failed to send transaction %d: %v", txIdxCounter, err) - time.Sleep(1 * time.Second) - continue - } - - txIdxCounter++ - totalTxCount.Add(1) - blockTxCount++ - - // Process pending transactions periodically with 1 second intervals - if txIdxCounter%10 == 0 { - s.processPendingTransactions(ctx) - - s.contractsMutex.Lock() - contractCount := len(s.deployedContracts) - s.contractsMutex.Unlock() - - s.logger.Infof("Progress: sent %d txs, deployed %d contracts", txIdxCounter, contractCount) - } - - // Small delay to prevent overwhelming the RPC - time.Sleep(100 * time.Millisecond) + if s.options.MaxPending > 0 { + maxPending = s.options.MaxPending } - // Wait for all pending transactions to complete with 1 second intervals - s.logger.Info("Waiting for remaining transactions to complete...") - for { - s.processPendingTransactions(ctx) + err := scenario.RunTransactionScenario(ctx, scenario.TransactionScenarioOptions{ + TotalCount: s.options.MaxTransactions, + Throughput: maxTxsPerBlock, + MaxPending: maxPending, + WalletPool: s.walletPool, - s.pendingTxsMutex.RLock() - pendingCount := len(s.pendingTxs) - s.pendingTxsMutex.RUnlock() + Logger: s.logger, + ProcessNextTxFn: func(ctx context.Context, txIdx uint64, onComplete func()) (func(), error) { + logger := s.logger + tx, err := s.sendTransaction(ctx, txIdx, onComplete) - if pendingCount == 0 { - break - } + atomic.AddUint64(&totalTxCount, 1) - s.logger.Infof("Waiting for %d pending transactions...", pendingCount) - time.Sleep(1 * time.Second) // Changed from 2 seconds to 1 second - } - - // Stop block monitoring before final cleanup - s.stopBlockMonitor() + return func() { + if err != nil { + logger.Warnf("could not send transaction: %v", err) + } else { + logger.Debugf("sent deployment tx #%6d: %v", txIdx+1, tx.Hash().String()) + } + }, err + }, + }) // Log any remaining unlogged blocks (final blocks) - keep this as final safety net s.blockStatsMutex.Lock() @@ -562,21 +361,21 @@ func (s *Scenario) Run(ctx context.Context) error { s.contractsMutex.Unlock() s.logger.WithFields(logrus.Fields{ - "total_txs": totalTxCount.Load(), + "total_txs": totalTxCount, "total_contracts": totalContracts, }).Info("All transactions completed") - return nil + return err } // sendTransaction sends a single contract deployment transaction -func (s *Scenario) sendTransaction(ctx context.Context, txIdx uint64) error { +func (s *Scenario) sendTransaction(ctx context.Context, txIdx uint64, onComplete func()) (*types.Transaction, error) { maxRetries := 3 for attempt := 0; attempt < maxRetries; attempt++ { - err := s.attemptTransaction(ctx, txIdx, attempt) + tx, err := s.attemptTransaction(ctx, txIdx, attempt, onComplete) if err == nil { - return nil + return tx, nil } // Check if it's a base fee error @@ -594,10 +393,10 @@ func (s *Scenario) sendTransaction(ctx context.Context, txIdx uint64) error { } // For other errors, return immediately - return err + return nil, err } - return fmt.Errorf("failed to send transaction after %d attempts", maxRetries) + return nil, fmt.Errorf("failed to send transaction after %d attempts", maxRetries) } // updateDynamicFees queries the network and updates base fee and tip fee @@ -638,78 +437,81 @@ func (s *Scenario) updateDynamicFees(ctx context.Context) error { } // attemptTransaction makes a single attempt to send a transaction -func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, attempt int) error { +func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, attempt int, onComplete func()) (*types.Transaction, error) { // Get client and wallet client := s.walletPool.GetClient(spamoor.SelectClientRoundRobin, 0, "") - wallet := s.walletPool.GetRootWallet() + wallet := s.walletPool.GetWallet(spamoor.SelectWalletByIndex, int(txIdx)) if client == nil { - return fmt.Errorf("no client available") + return nil, fmt.Errorf("no client available") } if wallet == nil { - return fmt.Errorf("no wallet available") - } - - // Get cached chain ID - chainID, err := s.getChainID(ctx) - if err != nil { - return fmt.Errorf("failed to get chain ID: %w", err) - } - - // Get current nonce for this wallet - addr := crypto.PubkeyToAddress(wallet.GetPrivateKey().PublicKey) - nonce, err := client.GetEthClient().PendingNonceAt(ctx, addr) - if err != nil { - return fmt.Errorf("failed to get nonce for %s: %w", addr.Hex(), err) + return nil, fmt.Errorf("no wallet available") } - // Create transaction auth - auth, err := bind.NewKeyedTransactorWithChainID(wallet.GetPrivateKey(), chainID) - if err != nil { - return fmt.Errorf("failed to create auth: %w", err) - } - - auth.Nonce = big.NewInt(int64(nonce)) - auth.Value = big.NewInt(0) - auth.GasLimit = 5200000 // Fixed gas limit for contract deployment - // Set EIP-1559 fee parameters - if s.options.BaseFee > 0 { - auth.GasFeeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(1000000000)) - } - if s.options.TipFee > 0 { - auth.GasTipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(1000000000)) + feeCap, tipCap, err := s.walletPool.GetTxPool().GetSuggestedFees(client, s.options.BaseFee, s.options.TipFee) + if err != nil { + return nil, fmt.Errorf("failed to get suggested fees: %w", err) } // Generate random salt for unique contract salt := make([]byte, 32) _, err = rand.Read(salt) if err != nil { - return fmt.Errorf("failed to generate salt: %w", err) + return nil, fmt.Errorf("failed to generate salt: %w", err) } saltInt := new(big.Int).SetBytes(salt) // Deploy the contract ethClient := client.GetEthClient() if ethClient == nil { - return fmt.Errorf("failed to get eth client") + return nil, fmt.Errorf("failed to get eth client") } - _, tx, _, err := contract.DeployContract(auth, ethClient, saltInt) + tx, err := wallet.BuildBoundTx(ctx, &txbuilder.TxMetadata{ + GasFeeCap: uint256.MustFromBig(feeCap), + GasTipCap: uint256.MustFromBig(tipCap), + Gas: 5200000, + Value: uint256.NewInt(0), + }, func(transactOpts *bind.TransactOpts) (*types.Transaction, error) { + _, deployTx, _, err := contract.DeployStateBloatToken(transactOpts, client.GetEthClient(), saltInt) + return deployTx, err + }) + if err != nil { - return fmt.Errorf("failed to deploy contract: %w", err) + return nil, fmt.Errorf("failed to create deployment transaction: %w", err) } - // Track pending transaction - pendingTx := &PendingTransaction{ - TxHash: tx.Hash(), - PrivateKey: wallet.GetPrivateKey(), - Timestamp: time.Now(), - } + mu := sync.Mutex{} + mu.Lock() + defer mu.Unlock() - s.pendingTxsMutex.Lock() - s.pendingTxs[tx.Hash()] = pendingTx - s.pendingTxsMutex.Unlock() + var callOnComplete bool - return nil + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + Client: client, + Rebroadcast: true, + OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + defer func() { + mu.Lock() + defer mu.Unlock() + + if callOnComplete { + onComplete() + } + }() + + if receipt != nil { + s.recordDeployedContract(receipt.ContractAddress, wallet.GetPrivateKey(), receipt, tx.Hash()) + } + }, + }) + + callOnComplete = err == nil + if err != nil { + return nil, err + } + + return tx, nil } From 977b885f52c9838a4824503ae2bfbfce9fe30cc8 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 16:48:13 +0200 Subject: [PATCH 33/39] fixes for `statebloat-erc20-max-transfers` scenario --- .../contract_deploy/contract_deploy.go | 13 ++- .../erc20_max_transfers.go | 96 ++++++++----------- 2 files changed, 49 insertions(+), 60 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index 220f23bb..bcb5936f 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -36,6 +36,7 @@ type ScenarioOptions struct { TipFee uint64 `yaml:"tip_fee"` ClientGroup string `yaml:"client_group"` MaxTransactions uint64 `yaml:"max_transactions"` + DeploymentsFile string `yaml:"deployments_file"` } // ContractDeployment tracks a deployed contract with its deployer info @@ -73,6 +74,7 @@ var ScenarioDefaultOptions = ScenarioOptions{ BaseFee: 5, // Moderate base fee (5 gwei) TipFee: 1, // Priority fee (1 gwei) MaxTransactions: 0, + DeploymentsFile: "deployments.json", } var ScenarioDescriptor = scenario.Descriptor{ Name: ScenarioName, @@ -94,6 +96,7 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Tip fee per gas in gwei") flags.StringVar(&s.options.ClientGroup, "client-group", ScenarioDefaultOptions.ClientGroup, "Client group to use for sending transactions") flags.Uint64Var(&s.options.MaxTransactions, "max-transactions", ScenarioDefaultOptions.MaxTransactions, "Maximum number of transactions to send (0 = use rate limiting based on block gas limit)") + flags.StringVar(&s.options.DeploymentsFile, "deployments-file", ScenarioDefaultOptions.DeploymentsFile, "File to save deployments to") return nil } @@ -194,6 +197,10 @@ func max(a, b int) int { // saveDeploymentsMapping creates/updates deployments.json with private key to contract address mapping func (s *Scenario) saveDeploymentsMapping() error { + if s.options.DeploymentsFile == "" { + return nil + } + // Create a map from private key to array of contract addresses deploymentMap := make(map[string][]string) @@ -204,9 +211,9 @@ func (s *Scenario) saveDeploymentsMapping() error { } // Create or overwrite the deployments.json file - deploymentsFile, err := os.Create("deployments.json") + deploymentsFile, err := os.Create(s.options.DeploymentsFile) if err != nil { - return fmt.Errorf("failed to create deployments.json file: %w", err) + return fmt.Errorf("failed to create %v file: %w", s.options.DeploymentsFile, err) } defer deploymentsFile.Close() @@ -215,7 +222,7 @@ func (s *Scenario) saveDeploymentsMapping() error { encoder.SetIndent("", " ") err = encoder.Encode(deploymentMap) if err != nil { - return fmt.Errorf("failed to write deployments.json: %w", err) + return fmt.Errorf("failed to write %v: %w", s.options.DeploymentsFile, err) } return nil diff --git a/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go b/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go index 51c000d0..29d73e26 100644 --- a/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go +++ b/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go @@ -1,4 +1,4 @@ -package erc20maxtransfers +package sberc20maxtransfers import ( "context" @@ -24,8 +24,8 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/pflag" + "github.com/ethpandaops/spamoor/scenario" contract "github.com/ethpandaops/spamoor/scenarios/statebloat/contract_deploy/contract" - "github.com/ethpandaops/spamoor/scenariotypes" "github.com/ethpandaops/spamoor/spamoor" "github.com/ethpandaops/spamoor/txbuilder" ) @@ -76,9 +76,10 @@ const ( // ScenarioOptions defines the configuration options for the scenario type ScenarioOptions struct { - BaseFee uint64 `yaml:"base_fee"` - TipFee uint64 `yaml:"tip_fee"` - Contract string `yaml:"contract"` + BaseFee uint64 `yaml:"base_fee"` + TipFee uint64 `yaml:"tip_fee"` + Contract string `yaml:"contract"` + DeploymentsFile string `yaml:"deployments_file"` } // DeploymentEntry represents a contract deployment from deployments.json @@ -106,7 +107,7 @@ type Scenario struct { // Deployed contracts and private key deployerPrivateKey string deployerAddress common.Address - deployerWallet *txbuilder.Wallet // Store the wallet instance + deployerWallet *spamoor.Wallet // Store the wallet instance deployedContracts []common.Address currentRoundContract common.Address // Contract being used for current round contractsLock sync.Mutex @@ -124,20 +125,21 @@ type Scenario struct { contractStatsLock sync.Mutex } -var ScenarioName = "erc20-max-transfers" +var ScenarioName = "statebloat-erc20-max-transfers" var ScenarioDefaultOptions = ScenarioOptions{ - BaseFee: DefaultBaseFeeGwei, - TipFee: DefaultTipFeeGwei, - Contract: "", + BaseFee: DefaultBaseFeeGwei, + TipFee: DefaultTipFeeGwei, + Contract: "", + DeploymentsFile: "deployments.json", } -var ScenarioDescriptor = scenariotypes.ScenarioDescriptor{ +var ScenarioDescriptor = scenario.Descriptor{ Name: ScenarioName, Description: "Maximum ERC20 transfers per block to unique addresses", DefaultOptions: ScenarioDefaultOptions, NewScenario: newScenario, } -func newScenario(logger logrus.FieldLogger) scenariotypes.Scenario { +func newScenario(logger logrus.FieldLogger) scenario.Scenario { return &Scenario{ logger: logger.WithField("scenario", ScenarioName), usedAddresses: make(map[common.Address]bool), @@ -149,14 +151,15 @@ func (s *Scenario) Flags(flags *pflag.FlagSet) error { flags.Uint64Var(&s.options.BaseFee, "basefee", ScenarioDefaultOptions.BaseFee, "Max fee per gas to use in transactions (in gwei)") flags.Uint64Var(&s.options.TipFee, "tipfee", ScenarioDefaultOptions.TipFee, "Max tip per gas to use in transactions (in gwei)") flags.StringVar(&s.options.Contract, "contract", ScenarioDefaultOptions.Contract, "Specific contract address to use (default: rotate through all)") + flags.StringVar(&s.options.DeploymentsFile, "deployments-file", ScenarioDefaultOptions.DeploymentsFile, "File to save deployments to") return nil } -func (s *Scenario) Init(walletPool *spamoor.WalletPool, config string) error { - s.walletPool = walletPool +func (s *Scenario) Init(options *scenario.Options) error { + s.walletPool = options.WalletPool - if config != "" { - err := yaml.Unmarshal([]byte(config), &s.options) + if options.Config != "" { + err := yaml.Unmarshal([]byte(options.Config), &s.options) if err != nil { return fmt.Errorf("failed to unmarshal config: %w", err) } @@ -187,9 +190,13 @@ func (s *Scenario) Config() string { // loadDeployedContracts loads contract addresses and private key from deployments.json func (s *Scenario) loadDeployedContracts() error { - data, err := os.ReadFile("deployments.json") + if s.options.DeploymentsFile == "" { + return fmt.Errorf("deployments file is not set") + } + + data, err := os.ReadFile(s.options.DeploymentsFile) if err != nil { - return fmt.Errorf("failed to read deployments.json: %w", err) + return fmt.Errorf("failed to read %v: %w", s.options.DeploymentsFile, err) } var deployments DeploymentEntry @@ -201,9 +208,8 @@ func (s *Scenario) loadDeployedContracts() error { // Get the first (and only) entry for privateKey, addresses := range deployments { // Trim 0x prefix if present - if strings.HasPrefix(privateKey, "0x") { - privateKey = privateKey[2:] - } + privateKey = strings.TrimPrefix(privateKey, "0x") + s.deployerPrivateKey = privateKey s.deployedContracts = make([]common.Address, len(addresses)) for i, addr := range addresses { @@ -248,7 +254,7 @@ func (s *Scenario) loadDeployedContracts() error { // loadTransferABI loads the transfer function ABI from the contract func (s *Scenario) loadTransferABI() error { // Parse the contract ABI to get the transfer method - contractABI, err := abi.JSON(strings.NewReader(contract.ContractMetaData.ABI)) + contractABI, err := abi.JSON(strings.NewReader(contract.StateBloatTokenMetaData.ABI)) if err != nil { return fmt.Errorf("failed to parse contract ABI: %w", err) } @@ -265,7 +271,7 @@ func (s *Scenario) loadTransferABI() error { // getNetworkBlockGasLimit retrieves the current block gas limit from the network // It waits for a new block to be mined (with timeout) to ensure fresh data -func (s *Scenario) getNetworkBlockGasLimit(ctx context.Context, client *txbuilder.Client) uint64 { +func (s *Scenario) getNetworkBlockGasLimit(ctx context.Context, client *spamoor.Client) uint64 { // Create a timeout context for the entire operation timeoutCtx, cancel := context.WithTimeout(ctx, BlockMiningTimeout) defer cancel() @@ -481,7 +487,7 @@ func (s *Scenario) runMaxTransfersMode(ctx context.Context) error { // Prepare the deployer wallet if not already done if s.deployerWallet == nil { // Create wallet from deployer private key - deployerWallet, err := txbuilder.NewWallet(s.deployerPrivateKey) + deployerWallet, err := spamoor.NewWallet(s.deployerPrivateKey) if err != nil { return fmt.Errorf("failed to create deployer wallet: %w", err) } @@ -584,7 +590,7 @@ func (s *Scenario) runMaxTransfersMode(ctx context.Context) error { } } -func (s *Scenario) sendMaxTransfers(ctx context.Context, deployerWallet *txbuilder.Wallet, targetTransfers int, targetGasLimit uint64, blockCounter int, client *txbuilder.Client) (uint64, string, int, float64, int, error) { +func (s *Scenario) sendMaxTransfers(ctx context.Context, deployerWallet *spamoor.Wallet, targetTransfers int, targetGasLimit uint64, blockCounter int, client *spamoor.Client) (uint64, string, int, float64, int, error) { // Select a random contract for this round contractForRound, err := s.selectRandomContract() if err != nil { @@ -599,40 +605,16 @@ func (s *Scenario) sendMaxTransfers(ctx context.Context, deployerWallet *txbuild s.logger.Infof("Selected contract for round #%d: %s", blockCounter, contractForRound.Hex()) // Get suggested fees or use configured values - var feeCap *big.Int - var tipCap *big.Int - - if s.options.BaseFee > 0 { - feeCap = new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(GweiPerEth)) - } - if s.options.TipFee > 0 { - tipCap = new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(GweiPerEth)) - } - - if feeCap == nil || tipCap == nil { - var err error - feeCap, tipCap, err = client.GetSuggestedFee(s.walletPool.GetContext()) - if err != nil { - return 0, "", 0, 0, 0, fmt.Errorf("failed to get suggested fees: %w", err) - } - } - - // Ensure minimum gas prices for inclusion - minFeeCap := new(big.Int).Mul(big.NewInt(int64(s.options.BaseFee)), big.NewInt(GweiPerEth)) - minTipCap := new(big.Int).Mul(big.NewInt(int64(s.options.TipFee)), big.NewInt(GweiPerEth)) - - if feeCap.Cmp(minFeeCap) < 0 { - feeCap = minFeeCap - } - if tipCap.Cmp(minTipCap) < 0 { - tipCap = minTipCap + feeCap, tipCap, err := s.walletPool.GetTxPool().GetSuggestedFees(client, s.options.BaseFee, s.options.TipFee) + if err != nil { + return 0, "", 0, 0, 0, fmt.Errorf("failed to get suggested fees: %w", err) } // Send transfers in batches return s.sendTransferBatch(ctx, deployerWallet, targetTransfers, targetGasLimit, blockCounter, client, feeCap, tipCap) } -func (s *Scenario) sendTransferBatch(ctx context.Context, wallet *txbuilder.Wallet, targetTransfers int, targetGasLimit uint64, iteration int, client *txbuilder.Client, feeCap, tipCap *big.Int) (uint64, string, int, float64, int, error) { +func (s *Scenario) sendTransferBatch(ctx context.Context, wallet *spamoor.Wallet, targetTransfers int, targetGasLimit uint64, iteration int, client *spamoor.Client, feeCap, tipCap *big.Int) (uint64, string, int, float64, int, error) { var confirmedCount int64 var uniqueRecipientsCount int64 var totalGasUsed uint64 @@ -712,9 +694,9 @@ func (s *Scenario) sendTransferBatch(ctx context.Context, wallet *txbuilder.Wall capturedContract := contractAddr // Send transaction - err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &txbuilder.SendTransactionOptions{ - Client: client, - MaxRebroadcasts: 0, // No retries to avoid duplicates + err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + Client: client, + Rebroadcast: false, // No retries to avoid duplicates OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { if err != nil { return // Don't log individual failures @@ -735,7 +717,7 @@ func (s *Scenario) sendTransferBatch(ctx context.Context, wallet *txbuilder.Wall } } }, - LogFn: func(client *txbuilder.Client, retry int, rebroadcast int, err error) { + LogFn: func(client *spamoor.Client, retry int, rebroadcast int, err error) { // Only log actual send failures if err != nil { s.logger.Debugf("transfer tx send failed: %v", err) From e36dcefa54f04e2d4447362c6e16f29edbbf6142 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 21:47:09 +0200 Subject: [PATCH 34/39] update for latest master changes --- .../contract_deploy/contract_deploy.go | 2 +- .../eoa_delegation/eoa_delegation.go | 40 +-------- .../erc20_max_transfers.go | 2 +- .../rand_sstore/rand_sstore_bloater.go | 82 ++++--------------- 4 files changed, 21 insertions(+), 105 deletions(-) diff --git a/scenarios/statebloat/contract_deploy/contract_deploy.go b/scenarios/statebloat/contract_deploy/contract_deploy.go index bcb5936f..8c08b7b4 100644 --- a/scenarios/statebloat/contract_deploy/contract_deploy.go +++ b/scenarios/statebloat/contract_deploy/contract_deploy.go @@ -499,7 +499,7 @@ func (s *Scenario) attemptTransaction(ctx context.Context, txIdx uint64, attempt err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ Client: client, Rebroadcast: true, - OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + OnComplete: func(tx *types.Transaction, receipt *types.Receipt, err error) { defer func() { mu.Lock() defer mu.Unlock() diff --git a/scenarios/statebloat/eoa_delegation/eoa_delegation.go b/scenarios/statebloat/eoa_delegation/eoa_delegation.go index 32d63f46..e9eb9400 100644 --- a/scenarios/statebloat/eoa_delegation/eoa_delegation.go +++ b/scenarios/statebloat/eoa_delegation/eoa_delegation.go @@ -368,7 +368,7 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ Client: client, Rebroadcast: false, // No retries to avoid duplicates - OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + OnComplete: func(tx *types.Transaction, receipt *types.Receipt, err error) { defer wg.Done() defer onComplete() @@ -611,45 +611,13 @@ func (s *Scenario) sendSingleMaxBloatingTransaction(ctx context.Context, authori s.logger.WithField("scenario", "eoa-delegation").Infof("MAX BLOATING TX SIZE: %d bytes (%.2f KiB) | Limit: %d bytes (%.1f KiB) | %d authorizations | Exceeds limit: %v", txSize, sizeKiB, MaxTransactionSize, limitKiB, len(authorizations), exceedsLimit) - wg := sync.WaitGroup{} - wg.Add(1) - - var txreceipt *types.Receipt - var txerr error - // Send the transaction - err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + txreceipt, txerr := s.walletPool.GetTxPool().SendAndAwaitTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ Client: client, Rebroadcast: true, - OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { - txreceipt = receipt - txerr = err - wg.Done() - }, - LogFn: func(client *spamoor.Client, retry int, rebroadcast int, err error) { - logger := s.logger.WithField("rpc", client.GetName()) - if retry > 0 { - logger = logger.WithField("retry", retry) - } - if rebroadcast > 0 { - logger = logger.WithField("rebroadcast", rebroadcast) - } - if err != nil { - logger.Errorf("failed sending max bloating tx: %v", err) - } else if retry > 0 || rebroadcast > 0 { - logger.Infof("successfully sent max bloating tx") - } - }, + LogFn: spamoor.GetDefaultLogFn(s.logger, "max bloating", "", tx), }) - if err != nil { - wallet.ResetPendingNonce(ctx, client) - return 0, "", 0, 0, 0, "", fmt.Errorf("failed to send max bloating transaction: %w", err) - } - - // Wait for transaction confirmation - wg.Wait() - if txerr != nil { return 0, "", 0, 0, 0, "", fmt.Errorf("failed to send max bloating transaction: %w", txerr) } @@ -728,7 +696,7 @@ func (s *Scenario) sendBatchedMaxBloatingTransactions(ctx context.Context, batch err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ Client: client, Rebroadcast: true, - OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + OnComplete: func(tx *types.Transaction, receipt *types.Receipt, err error) { txreceipts[batchIndex] = receipt txerrs[batchIndex] = err wg.Done() diff --git a/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go b/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go index 29d73e26..f271a324 100644 --- a/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go +++ b/scenarios/statebloat/erc20_max_transfers/erc20_max_transfers.go @@ -697,7 +697,7 @@ func (s *Scenario) sendTransferBatch(ctx context.Context, wallet *spamoor.Wallet err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ Client: client, Rebroadcast: false, // No retries to avoid duplicates - OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { + OnComplete: func(tx *types.Transaction, receipt *types.Receipt, err error) { if err != nil { return // Don't log individual failures } diff --git a/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go index c58586a3..5ad0ea89 100644 --- a/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go +++ b/scenarios/statebloat/rand_sstore/rand_sstore_bloater.go @@ -233,33 +233,15 @@ func (s *Scenario) deployContract(ctx context.Context) error { return err } - var txReceipt *types.Receipt - var txErr error - txWg := sync.WaitGroup{} - txWg.Add(1) - - err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + txreceipt, err := s.walletPool.GetTxPool().SendAndAwaitTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ Client: client, Rebroadcast: true, - OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { - defer func() { - txWg.Done() - }() - - txErr = err - txReceipt = receipt - }, }) if err != nil { return err } - txWg.Wait() - if txErr != nil { - return err - } - - s.contractAddress = txReceipt.ContractAddress + s.contractAddress = txreceipt.ContractAddress s.contractInstance, err = contract.NewSSTOREStorageBloater(s.contractAddress, client.GetEthClient()) if err != nil { return err @@ -372,74 +354,40 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo return err } - var txReceipt *types.Receipt - var txErr error - txWg := sync.WaitGroup{} - txWg.Add(1) - - err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ + txreceipt, txerr := s.walletPool.GetTxPool().SendAndAwaitTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ Client: client, Rebroadcast: true, - OnConfirm: func(tx *types.Transaction, receipt *types.Receipt, err error) { - if receipt != nil { - txFees := utils.GetTransactionFees(tx, receipt) - s.logger.WithField("rpc", client.GetName()).Debugf(" transaction confirmed in block #%v. total fee: %v gwei (base: %v) logs: %v", receipt.BlockNumber.String(), txFees.TotalFeeGwei(), txFees.TxBaseFeeGwei(), len(receipt.Logs)) - } - txErr = err - txReceipt = receipt - txWg.Done() - }, - LogFn: func(client *spamoor.Client, retry int, rebroadcast int, err error) { - logger := s.logger.WithField("rpc", client.GetName()).WithField("nonce", tx.Nonce()) - if retry == 0 && rebroadcast > 0 { - logger.Infof("rebroadcasting tx") - } - if retry > 0 { - logger = logger.WithField("retry", retry) - } - if rebroadcast > 0 { - logger = logger.WithField("rebroadcast", rebroadcast) - } - if err != nil { - logger.Debugf("failed sending tx: %v", err) - } else if retry > 0 || rebroadcast > 0 { - logger.Debugf("successfully sent tx") - } - }, + LogFn: spamoor.GetDefaultLogFn(s.logger, "rand-sstore", "", tx), }) - if err != nil { - // reset nonce if tx was not sent - wallet.ResetPendingNonce(ctx, client) - return err + if txerr != nil { + return fmt.Errorf("transaction failed: %w", txerr) } - txWg.Wait() - if txErr != nil { - return fmt.Errorf("transaction failed: %w", txErr) - } - - if txReceipt == nil || txReceipt.Status != 1 { + if txreceipt == nil || txreceipt.Status != 1 { // Increase our gas estimate by 10% s.actualGasPerNewSlotIteration = uint64(float64(s.actualGasPerNewSlotIteration) * 1.1) return fmt.Errorf("transaction rejected") } + txFees := utils.GetTransactionFees(tx, txreceipt) + s.logger.WithField("rpc", client.GetName()).Debugf(" transaction confirmed in block #%v. total fee: %v gwei (base: %v) logs: %v", txreceipt.BlockNumber.String(), txFees.TotalFeeGwei(), txFees.TxBaseFeeGwei(), len(txreceipt.Logs)) + // Mark this slot count as successful s.successfulSlotCounts[slotsToCreate] = true // Update metrics and adaptive gas tracking s.totalSlots += slotsToCreate totalOverhead := BaseTxCost + FunctionCallOverhead - actualGasPerSlotIteration := (txReceipt.GasUsed - totalOverhead) / slotsToCreate + actualGasPerSlotIteration := (txreceipt.GasUsed - totalOverhead) / slotsToCreate // Update our gas estimate using exponential moving average // New estimate = 0.7 * old estimate + 0.3 * actual s.actualGasPerNewSlotIteration = uint64(float64(s.actualGasPerNewSlotIteration)*0.7 + float64(actualGasPerSlotIteration)*0.3) // Get previous block info for tracking - prevBlockNumber := txReceipt.BlockNumber.Uint64() - 1 + prevBlockNumber := txreceipt.BlockNumber.Uint64() - 1 prevBlock, err := client.GetEthClient().BlockByNumber(ctx, big.NewInt(int64(prevBlockNumber))) if err != nil { @@ -469,11 +417,11 @@ func (s *Scenario) executeCreateSlots(ctx context.Context, targetGas uint64, blo mbWrittenThisTx := float64(slotsToCreate*64) / (1024 * 1024) // Calculate block utilization percentage - blockUtilization := float64(txReceipt.GasUsed) / float64(blockGasLimit) * 100 + blockUtilization := float64(txreceipt.GasUsed) / float64(blockGasLimit) * 100 s.logger.WithFields(logrus.Fields{ - "block_number": txReceipt.BlockNumber, - "gas_used": txReceipt.GasUsed, + "block_number": txreceipt.BlockNumber, + "gas_used": txreceipt.GasUsed, "slots_created": slotsToCreate, "gas_per_slot": actualGasPerSlotIteration, "total_slots": s.totalSlots, From aacb43ee9b6f636878c7d27d054b5fe1ef1b83c8 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 19 Jun 2025 21:56:44 +0200 Subject: [PATCH 35/39] small fix --- scenarios/statebloat/eoa_delegation/eoa_delegation.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scenarios/statebloat/eoa_delegation/eoa_delegation.go b/scenarios/statebloat/eoa_delegation/eoa_delegation.go index e9eb9400..db65c416 100644 --- a/scenarios/statebloat/eoa_delegation/eoa_delegation.go +++ b/scenarios/statebloat/eoa_delegation/eoa_delegation.go @@ -311,7 +311,6 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in fundingAmount := uint256.NewInt(1) var confirmedCount int64 - wg := sync.WaitGroup{} delegatorIndexBase := uint64(iteration * FundingIterationOffset) // Large offset per iteration to avoid conflicts @@ -364,12 +363,10 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in // Send funding transaction with no retries to avoid duplicates transactionSubmitted = true - wg.Add(1) err = s.walletPool.GetTxPool().SendTransaction(ctx, wallet, tx, &spamoor.SendTransactionOptions{ Client: client, Rebroadcast: false, // No retries to avoid duplicates OnComplete: func(tx *types.Transaction, receipt *types.Receipt, err error) { - defer wg.Done() defer onComplete() if err != nil { @@ -430,7 +427,6 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in }) // Return the confirmed count - wg.Wait() confirmed := atomic.LoadInt64(&confirmedCount) return confirmed, nil } From 12821688c5a64d5719e162b88e3d9bb20de4888a Mon Sep 17 00:00:00 2001 From: pk910 Date: Fri, 20 Jun 2025 04:13:02 +0200 Subject: [PATCH 36/39] `go mod tidy` --- go.mod | 3 --- 1 file changed, 3 deletions(-) diff --git a/go.mod b/go.mod index 34285f22..d1150dbc 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( github.com/prometheus/client_golang v1.22.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/pflag v1.0.6 - github.com/stretchr/testify v1.10.0 github.com/swaggo/http-swagger v1.3.4 github.com/swaggo/swag v1.16.4 github.com/tdewolff/minify v2.3.6+incompatible @@ -35,7 +34,6 @@ require ( github.com/consensys/bavard v0.1.27 // indirect github.com/consensys/gnark-crypto v0.16.0 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect - github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -56,7 +54,6 @@ require ( github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.16.1 // indirect From b88a08f0fabc7c7232ba5a30d78b7a55ca9fe706 Mon Sep 17 00:00:00 2001 From: pk910 Date: Fri, 20 Jun 2025 15:33:20 +0200 Subject: [PATCH 37/39] add external wallets to wallet pool --- spamoor/walletpool.go | 149 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 142 insertions(+), 7 deletions(-) diff --git a/spamoor/walletpool.go b/spamoor/walletpool.go index 9fce1b4b..64abef3a 100644 --- a/spamoor/walletpool.go +++ b/spamoor/walletpool.go @@ -55,6 +55,16 @@ type WellKnownWalletConfig struct { VeryWellKnown bool } +// ExternalWalletConfig defines configuration for an external wallet imported into the pool. +// External wallets are not used for GetWallet calls but can optionally be funded. +type ExternalWalletConfig struct { + Name string + Wallet *Wallet + RefillAmount *uint256.Int + RefillBalance *uint256.Int + EnableFunding bool +} + // WalletPool manages a pool of child wallets derived from a root wallet with automatic funding // and balance monitoring. It provides wallet selection strategies, automatic refills when balances // drop below thresholds, and batch funding operations for efficiency. @@ -70,6 +80,7 @@ type WalletPool struct { childWallets []*Wallet wellKnownNames []*WellKnownWalletConfig wellKnownWallets map[string]*Wallet + externalWallets []*ExternalWalletConfig selectionMutex sync.Mutex rrWalletIdx int reclaimedFunds bool @@ -108,6 +119,7 @@ func NewWalletPool(ctx context.Context, logger logrus.FieldLogger, rootWallet *R txpool: txpool, childWallets: make([]*Wallet, 0), wellKnownWallets: make(map[string]*Wallet), + externalWallets: make([]*ExternalWalletConfig, 0), runFundings: true, } } @@ -174,6 +186,12 @@ func (pool *WalletPool) AddWellKnownWallet(config *WellKnownWalletConfig) { pool.wellKnownNames = append(pool.wellKnownNames, config) } +// AddExternalWallet adds an external wallet with custom funding configuration. +// External wallets are not part of the deterministic wallet generation but can optionally be tracked and funded. +func (pool *WalletPool) AddExternalWallet(config *ExternalWalletConfig) { + pool.externalWallets = append(pool.externalWallets, config) +} + // SetRefillAmount sets the amount sent to wallets when they need funding. func (pool *WalletPool) SetRefillAmount(amount *uint256.Int) { pool.config.RefillAmount = amount @@ -260,6 +278,17 @@ func (pool *WalletPool) GetWellKnownWallet(name string) *Wallet { return pool.wellKnownWallets[name] } +// GetExternalWallet returns an external wallet by name. +// Returns nil if the wallet doesn't exist. +func (pool *WalletPool) GetExternalWallet(name string) *Wallet { + for _, config := range pool.externalWallets { + if config.Name == name { + return config.Wallet + } + } + return nil +} + // GetVeryWellKnownWalletAddress derives the address of a "very well known" wallet // without registering it. Very well known wallets are derived only from the root // wallet's private key and the wallet name, without any scenario seed. @@ -308,17 +337,30 @@ func (pool *WalletPool) GetWalletName(address common.Address) string { } } + for _, config := range pool.externalWallets { + if config.Wallet != nil && config.Wallet.GetAddress() == address { + return config.Name + } + } + return "unknown" } -// GetAllWallets returns a slice containing all wallets (well-known and child wallets). +// GetAllWallets returns a slice containing all wallets (well-known, external, and child wallets). // The root wallet is not included in this list. func (pool *WalletPool) GetAllWallets() []*Wallet { - wallets := make([]*Wallet, len(pool.childWallets)+len(pool.wellKnownWallets)) - for i, config := range pool.wellKnownNames { - wallets[i] = pool.wellKnownWallets[config.Name] + totalCount := len(pool.childWallets) + len(pool.wellKnownWallets) + len(pool.externalWallets) + wallets := make([]*Wallet, totalCount) + idx := 0 + for _, config := range pool.wellKnownNames { + wallets[idx] = pool.wellKnownWallets[config.Name] + idx++ } - copy(wallets[len(pool.wellKnownWallets):], pool.childWallets) + for _, config := range pool.externalWallets { + wallets[idx] = config.Wallet + idx++ + } + copy(wallets[idx:], pool.childWallets) return wallets } @@ -392,6 +434,47 @@ func (pool *WalletPool) PrepareWallets() error { }(config) } + for _, config := range pool.externalWallets { + if config.EnableFunding && pool.runFundings { + wg.Add(1) + wl <- true + go func(config *ExternalWalletConfig) { + defer func() { + <-wl + wg.Done() + }() + if walletErr != nil { + return + } + + err := client.UpdateWallet(pool.ctx, config.Wallet) + if err != nil { + pool.logger.Errorf("could not update external wallet %v: %v", config.Name, err) + walletErr = err + return + } + + refillAmount := pool.config.RefillAmount + refillBalance := pool.config.RefillBalance + if config.RefillAmount != nil { + refillAmount = config.RefillAmount + } + if config.RefillBalance != nil { + refillBalance = config.RefillBalance + } + + if config.Wallet.GetBalance().Cmp(refillBalance.ToBig()) < 0 { + walletsMutex.Lock() + fundingReqs = append(fundingReqs, &FundingRequest{ + Wallet: config.Wallet, + Amount: refillAmount, + }) + walletsMutex.Unlock() + } + }(config) + } + } + for childIdx := uint64(0); childIdx < pool.config.WalletCount; childIdx++ { wg.Add(1) wl <- true @@ -564,7 +647,8 @@ func (pool *WalletPool) resupplyChildWallets() error { wl := make(chan bool, 50) wellKnownCount := uint64(len(pool.wellKnownWallets)) - fundingReqs := make([]*FundingRequest, 0, pool.config.WalletCount+wellKnownCount) + externalCount := uint64(len(pool.externalWallets)) + fundingReqs := make([]*FundingRequest, 0, pool.config.WalletCount+wellKnownCount+externalCount) reqsMutex := &sync.Mutex{} for idx, config := range pool.wellKnownNames { @@ -611,6 +695,47 @@ func (pool *WalletPool) resupplyChildWallets() error { }(idx, wellKnownWallet, config) } + for _, config := range pool.externalWallets { + if config.EnableFunding { + wg.Add(1) + wl <- true + go func(config *ExternalWalletConfig) { + defer func() { + <-wl + wg.Done() + }() + if walletErr != nil { + return + } + + refillAmount := pool.config.RefillAmount + refillBalance := pool.config.RefillBalance + + if config.RefillAmount != nil { + refillAmount = config.RefillAmount + } + if config.RefillBalance != nil { + refillBalance = config.RefillBalance + } + + err := client.UpdateWallet(pool.ctx, config.Wallet) + if err != nil { + walletErr = err + return + } + + if config.Wallet.GetBalance().Cmp(refillBalance.ToBig()) < 0 { + reqsMutex.Lock() + fundingReqs = append(fundingReqs, &FundingRequest{ + Wallet: config.Wallet, + Amount: refillAmount, + }) + reqsMutex.Unlock() + } + }(config) + } + } + for childIdx := uint64(0); childIdx < pool.config.WalletCount; childIdx++ { wg.Add(1) wl <- true @@ -876,7 +1001,7 @@ func (pool *WalletPool) buildWalletReclaimTx(ctx context.Context, childWallet *W return tx, nil } -// collectPoolWallets adds all wallets (root, child, and well-known) to the provided map. +// collectPoolWallets adds all wallets (root, child, well-known, and external) to the provided map. // This is used by the transaction pool to track which addresses belong to this wallet pool. func (pool *WalletPool) collectPoolWallets(walletMap map[common.Address]*Wallet) { walletMap[pool.rootWallet.wallet.GetAddress()] = pool.rootWallet.wallet @@ -886,6 +1011,11 @@ func (pool *WalletPool) collectPoolWallets(walletMap map[common.Address]*Wallet) for _, wallet := range pool.wellKnownWallets { walletMap[wallet.GetAddress()] = wallet } + for _, config := range pool.externalWallets { + if config.Wallet != nil { + walletMap[config.Wallet.GetAddress()] = config.Wallet + } + } } // CheckChildWalletBalance checks and refills a specific wallet if needed. @@ -987,6 +1117,11 @@ func (pool *WalletPool) ReclaimFunds(ctx context.Context, client *Client) error for _, wallet := range pool.wellKnownWallets { reclaimWallet(wallet) } + for _, config := range pool.externalWallets { + if config.Wallet != nil { + reclaimWallet(config.Wallet) + } + } reclaimWg.Wait() if len(reclaimTxs) > 0 { From 49c68e880327b3a9f9a41bda8d33200b1e36c2af Mon Sep 17 00:00:00 2001 From: pk910 Date: Sat, 21 Jun 2025 13:18:00 +0200 Subject: [PATCH 38/39] fix missing logger --- scenarios/statebloat/eoa_delegation/eoa_delegation.go | 1 + 1 file changed, 1 insertion(+) diff --git a/scenarios/statebloat/eoa_delegation/eoa_delegation.go b/scenarios/statebloat/eoa_delegation/eoa_delegation.go index db65c416..43473770 100644 --- a/scenarios/statebloat/eoa_delegation/eoa_delegation.go +++ b/scenarios/statebloat/eoa_delegation/eoa_delegation.go @@ -401,6 +401,7 @@ func (s *Scenario) fundMaxBloatingDelegators(ctx context.Context, targetCount in Throughput: maxTxsPerBlock * 2, MaxPending: maxTxsPerBlock * 2, WalletPool: s.walletPool, + Logger: s.logger, ProcessNextTxFn: func(ctx context.Context, txIdx uint64, onComplete func()) (func(), error) { logger := s.logger tx, client, wallet, err := fundNextDelegator(ctx, txIdx, onComplete) From 3abd2edf00d78d65e22bb03a8b8460068b008382 Mon Sep 17 00:00:00 2001 From: pk910 Date: Sat, 21 Jun 2025 13:28:16 +0200 Subject: [PATCH 39/39] fix for external wallet initialization --- spamoor/walletpool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spamoor/walletpool.go b/spamoor/walletpool.go index 64abef3a..c54254b9 100644 --- a/spamoor/walletpool.go +++ b/spamoor/walletpool.go @@ -385,7 +385,7 @@ func (pool *WalletPool) PrepareWallets() error { seed := pool.config.WalletSeed - if pool.config.WalletCount == 0 && len(pool.wellKnownWallets) == 0 { + if pool.config.WalletCount == 0 && len(pool.wellKnownWallets) == 0 && len(pool.externalWallets) == 0 { pool.childWallets = make([]*Wallet, 0) } else { var client *Client