diff --git a/README.md b/README.md index 9648be9..0ea339e 100644 --- a/README.md +++ b/README.md @@ -87,9 +87,7 @@ pragma solidity ^0.8.0; contract SimpleContract { function check(uint32 x, uint32 y) public pure { - if (x > 0 && x < 100 && y > 0 && y < 100) { - assert(x + y != 142); - } + assert(x + y != 142); } } ``` diff --git a/example/ERC721A.t.sol b/example/ERC721A.t.sol index 023b965..6501ae8 100644 --- a/example/ERC721A.t.sol +++ b/example/ERC721A.t.sol @@ -82,34 +82,37 @@ contract ERC721ATest is ERC721A { } function testMintRequirements(address to, uint quantity) public { - mint(to, quantity); - - assert(to != address(0)); - assert(quantity > 0); + if (to != address(0) && quantity > 0) { + mint(to, quantity); + } } function testMintNextTokenIdUpdate(address to, uint quantity) public { - uint oldNextTokenId = _nextTokenId(); - require(oldNextTokenId <= type(uint96).max); // practical assumption needed for overflow/underflow not occurring + if (to != address(0) && quantity > 0) { + uint oldNextTokenId = _nextTokenId(); + require(oldNextTokenId <= type(uint96).max); // practical assumption needed for overflow/underflow not occurring - mint(to, quantity); + mint(to, quantity); - uint newNextTokenId = _nextTokenId(); + uint newNextTokenId = _nextTokenId(); - assert(newNextTokenId >= oldNextTokenId); // ensuring no overflow - assert(newNextTokenId == oldNextTokenId + quantity); + assert(newNextTokenId >= oldNextTokenId); // ensuring no overflow + assert(newNextTokenId == oldNextTokenId + quantity); + } } function testMintBalanceUpdate(address to, uint quantity) public { - uint oldBalanceTo = balanceOf(to); - require(oldBalanceTo <= type(uint64).max / 2); // practical assumption needed for balance staying within uint64 + if (to != address(0) && quantity > 0) { + uint oldBalanceTo = balanceOf(to); + require(oldBalanceTo <= type(uint64).max / 2); // practical assumption needed for balance staying within uint64 - mint(to, quantity); + mint(to, quantity); - uint newBalanceTo = balanceOf(to); + uint newBalanceTo = balanceOf(to); - assert(newBalanceTo >= oldBalanceTo); // ensuring no overflow - assert(newBalanceTo == oldBalanceTo + quantity); + assert(newBalanceTo >= oldBalanceTo); // ensuring no overflow + assert(newBalanceTo == oldBalanceTo + quantity); + } } function testMintOwnershipUpdate(address to, uint quantity, uint _newNextTokenId) public { diff --git a/example/build/ERC721A.bin b/example/build/ERC721A.bin index 4ff922e..6539627 100644 --- a/example/build/ERC721A.bin +++ b/example/build/ERC721A.bin @@ -1 +1 @@ -608060405234801562000010575f80fd5b5060405162001f6138038062001f61833981810160405281019062000036919062000200565b8160029081620000479190620004ba565b508060039081620000599190620004ba565b506200006a6200007760201b60201c565b5f8190555050506200059e565b5f90565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000dc8262000094565b810181811067ffffffffffffffff82111715620000fe57620000fd620000a4565b5b80604052505050565b5f620001126200007b565b9050620001208282620000d1565b919050565b5f67ffffffffffffffff821115620001425762000141620000a4565b5b6200014d8262000094565b9050602081019050919050565b5f5b83811015620001795780820151818401526020810190506200015c565b5f8484015250505050565b5f6200019a620001948462000125565b62000107565b905082815260208101848484011115620001b957620001b862000090565b5b620001c68482856200015a565b509392505050565b5f82601f830112620001e557620001e46200008c565b5b8151620001f784826020860162000184565b91505092915050565b5f806040838503121562000219576200021862000084565b5b5f83015167ffffffffffffffff81111562000239576200023862000088565b5b6200024785828601620001ce565b925050602083015167ffffffffffffffff8111156200026b576200026a62000088565b5b6200027985828601620001ce565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002d257607f821691505b602082108103620002e857620002e76200028d565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200034c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200030f565b6200035886836200030f565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620003a26200039c620003968462000370565b62000379565b62000370565b9050919050565b5f819050919050565b620003bd8362000382565b620003d5620003cc82620003a9565b8484546200031b565b825550505050565b5f90565b620003eb620003dd565b620003f8818484620003b2565b505050565b5b818110156200041f57620004135f82620003e1565b600181019050620003fe565b5050565b601f8211156200046e576200043881620002ee565b620004438462000300565b8101602085101562000453578190505b6200046b620004628562000300565b830182620003fd565b50505b505050565b5f82821c905092915050565b5f620004905f198460080262000473565b1980831691505092915050565b5f620004aa83836200047f565b9150826002028217905092915050565b620004c58262000283565b67ffffffffffffffff811115620004e157620004e0620000a4565b5b620004ed8254620002ba565b620004fa82828562000423565b5f60209050601f83116001811462000530575f84156200051b578287015190505b6200052785826200049d565b86555062000596565b601f1984166200054086620002ee565b5f5b82811015620005695784890151825560018201915060208501945060208101905062000542565b8683101562000589578489015162000585601f8916826200047f565b8355505b6001600288020188555050505b505050505050565b6119b580620005ac5f395ff3fe608060405260043610610113575f3560e01c8063625553e21161009f578063a7cc013611610063578063a7cc0136146103a3578063b88d4fde146103df578063c87b56dd146103fb578063d9d21c6314610437578063e985e9c51461046157610113565b8063625553e2146102af5780636352211e146102d957806370a082311461031557806395d89b4114610351578063a22cb4651461037b57610113565b806318160ddd116100e657806318160ddd146101d557806323b872dd146101ff57806342842e0e1461021b578063444996c11461023757806347f69eba1461027357610113565b806301ffc9a71461011757806306fdde0314610153578063081812fc1461017d578063095ea7b3146101b9575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061127b565b61049d565b60405161014a91906112c0565b60405180910390f35b34801561015e575f80fd5b5061016761052e565b6040516101749190611363565b60405180910390f35b348015610188575f80fd5b506101a3600480360381019061019e91906113b6565b6105be565b6040516101b09190611420565b60405180910390f35b6101d360048036038101906101ce9190611463565b610617565b005b3480156101e0575f80fd5b506101e9610627565b6040516101f691906114b0565b60405180910390f35b610219600480360381019061021491906114c9565b61063c565b005b610235600480360381019061023091906114c9565b6108e7565b005b348015610242575f80fd5b5061025d600480360381019061025891906113b6565b610906565b60405161026a91906114b0565b60405180910390f35b34801561027e575f80fd5b50610299600480360381019061029491906113b6565b6109e8565b6040516102a691906114b0565b60405180910390f35b3480156102ba575f80fd5b506102c36109fd565b6040516102d091906114b0565b60405180910390f35b3480156102e4575f80fd5b506102ff60048036038101906102fa91906113b6565b610a1e565b60405161030c9190611420565b60405180910390f35b348015610320575f80fd5b5061033b60048036038101906103369190611519565b610a2f565b60405161034891906114b0565b60405180910390f35b34801561035c575f80fd5b50610365610ac3565b6040516103729190611363565b60405180910390f35b348015610386575f80fd5b506103a1600480360381019061039c919061156e565b610b53565b005b3480156103ae575f80fd5b506103c960048036038101906103c491906113b6565b610c59565b6040516103d69190611420565b60405180910390f35b6103f960048036038101906103f491906116d8565b610c92565b005b348015610406575f80fd5b50610421600480360381019061041c91906113b6565b610ce3565b60405161042e9190611363565b60405180910390f35b348015610442575f80fd5b5061044b610d5d565b60405161045891906114b0565b60405180910390f35b34801561046c575f80fd5b5061048760048036038101906104829190611758565b610d7e565b60405161049491906112c0565b60405180910390f35b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104f757506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806105275750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461053d906117c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610569906117c3565b80156105b45780601f1061058b576101008083540402835291602001916105b4565b820191905f5260205f20905b81548152906001019060200180831161059757829003601f168201915b5050505050905090565b5f6105c882610e0c565b6105dd576105dc63cf4700e460e01b610e7e565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61062382826001610e86565b5050565b5f610630610fb0565b6001545f540303905090565b5f61064682610906565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106bb576106ba63a114810060e01b610e7e565b5b5f806106c684610fb4565b915091506106dc81876106d7610fd7565b610fde565b610707576106f1866106ec610fd7565b610d7e565b610706576107056359c896be60e01b610e7e565b5b5b6107148686866001611021565b801561071e575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055506107e6856107c2888887611027565b7c02000000000000000000000000000000000000000000000000000000001761104e565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603610862575f6001850190505f60045f8381526020019081526020015f205403610860575f54811461085f578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036108d1576108d063ea553b3460e01b610e7e565b5b6108de8787876001611078565b50505050505050565b61090183838360405180602001604052805f815250610c92565b505050565b5f81610910610fb0565b116109d25760045f8381526020019081526020015f205490505f81036109aa575f5482106109495761094863df2d9b4260e01b610e7e565b5b5b60045f836001900393508381526020019081526020015f205490505f8103156109a5575f7c0100000000000000000000000000000000000000000000000000000000821603156109e3576109a463df2d9b4260e01b610e7e565b5b61094a565b5f7c0100000000000000000000000000000000000000000000000000000000821603156109e3575b6109e263df2d9b4260e01b610e7e565b5b919050565b6004602052805f5260405f205f915090505481565b7c020000000000000000000000000000000000000000000000000000000081565b5f610a2882610906565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610a7457610a73638f4eb60460e01b610e7e565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b606060038054610ad2906117c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610afe906117c3565b8015610b495780601f10610b2057610100808354040283529160200191610b49565b820191905f5260205f20905b815481529060010190602001808311610b2c57829003601f168201915b5050505050905090565b8060075f610b5f610fd7565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610c08610fd7565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610c4d91906112c0565b60405180910390a35050565b6006602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b610c9d84848461063c565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14610cdd57610cc78484848461107e565b610cdc57610cdb63d1a57ed660e01b610e7e565b5b5b50505050565b6060610cee82610e0c565b610d0357610d0263a14c4b5060e01b610e7e565b5b5f610d0c6111a8565b90505f815103610d2a5760405180602001604052805f815250610d55565b80610d34846111be565b604051602001610d4592919061182d565b6040516020818303038152906040525b915050919050565b7c010000000000000000000000000000000000000000000000000000000081565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f81610e16610fb0565b11610e79575f54821015610e78575f5b5f60045f8581526020019081526020015f205491508103610e525782610e4b9061187d565b9250610e26565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b919050565b805f5260045ffd5b5f610e9083610a1e565b9050818015610ed257508073ffffffffffffffffffffffffffffffffffffffff16610eb9610fd7565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610efe57610ee881610ee3610fd7565b610d7e565b610efd57610efc63cfb3b94260e01b610e7e565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f90565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e861103d86868461120d565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a026110a3610fd7565b8786866040518563ffffffff1660e01b81526004016110c594939291906118f6565b6020604051808303815f875af192505050801561110057506040513d601f19601f820116820180604052508101906110fd9190611954565b60015b611155573d805f811461112e576040519150601f19603f3d011682016040523d82523d5f602084013e611133565b606091505b505f81510361114d5761114c63d1a57ed660e01b610e7e565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606060405180602001604052805f815250905090565b606060a060405101806040526020810391505f825281835b6001156111f857600184039350600a81066030018453600a81049050806111d6575b50828103602084039350808452505050919050565b5f9392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61125a81611226565b8114611264575f80fd5b50565b5f8135905061127581611251565b92915050565b5f602082840312156112905761128f61121e565b5b5f61129d84828501611267565b91505092915050565b5f8115159050919050565b6112ba816112a6565b82525050565b5f6020820190506112d35f8301846112b1565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156113105780820151818401526020810190506112f5565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611335826112d9565b61133f81856112e3565b935061134f8185602086016112f3565b6113588161131b565b840191505092915050565b5f6020820190508181035f83015261137b818461132b565b905092915050565b5f819050919050565b61139581611383565b811461139f575f80fd5b50565b5f813590506113b08161138c565b92915050565b5f602082840312156113cb576113ca61121e565b5b5f6113d8848285016113a2565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61140a826113e1565b9050919050565b61141a81611400565b82525050565b5f6020820190506114335f830184611411565b92915050565b61144281611400565b811461144c575f80fd5b50565b5f8135905061145d81611439565b92915050565b5f80604083850312156114795761147861121e565b5b5f6114868582860161144f565b9250506020611497858286016113a2565b9150509250929050565b6114aa81611383565b82525050565b5f6020820190506114c35f8301846114a1565b92915050565b5f805f606084860312156114e0576114df61121e565b5b5f6114ed8682870161144f565b93505060206114fe8682870161144f565b925050604061150f868287016113a2565b9150509250925092565b5f6020828403121561152e5761152d61121e565b5b5f61153b8482850161144f565b91505092915050565b61154d816112a6565b8114611557575f80fd5b50565b5f8135905061156881611544565b92915050565b5f80604083850312156115845761158361121e565b5b5f6115918582860161144f565b92505060206115a28582860161155a565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115ea8261131b565b810181811067ffffffffffffffff82111715611609576116086115b4565b5b80604052505050565b5f61161b611215565b905061162782826115e1565b919050565b5f67ffffffffffffffff821115611646576116456115b4565b5b61164f8261131b565b9050602081019050919050565b828183375f83830152505050565b5f61167c6116778461162c565b611612565b905082815260208101848484011115611698576116976115b0565b5b6116a384828561165c565b509392505050565b5f82601f8301126116bf576116be6115ac565b5b81356116cf84826020860161166a565b91505092915050565b5f805f80608085870312156116f0576116ef61121e565b5b5f6116fd8782880161144f565b945050602061170e8782880161144f565b935050604061171f878288016113a2565b925050606085013567ffffffffffffffff8111156117405761173f611222565b5b61174c878288016116ab565b91505092959194509250565b5f806040838503121561176e5761176d61121e565b5b5f61177b8582860161144f565b925050602061178c8582860161144f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117da57607f821691505b6020821081036117ed576117ec611796565b5b50919050565b5f81905092915050565b5f611807826112d9565b61181181856117f3565b93506118218185602086016112f3565b80840191505092915050565b5f61183882856117fd565b915061184482846117fd565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61188782611383565b91505f820361189957611898611850565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6118c8826118a4565b6118d281856118ae565b93506118e28185602086016112f3565b6118eb8161131b565b840191505092915050565b5f6080820190506119095f830187611411565b6119166020830186611411565b61192360408301856114a1565b818103606083015261193581846118be565b905095945050505050565b5f8151905061194e81611251565b92915050565b5f602082840312156119695761196861121e565b5b5f61197684828501611940565b9150509291505056fea2646970667358221220d85a6e93d0e0fe8be64f551cb713c18838e3619b2f07d69c0b93678525fe6c1e64736f6c63430008180033 \ No newline at end of file +608060405234801561000f575f80fd5b50604051611eb6380380611eb6833981810160405281019061003191906101bc565b8160029081610040919061043f565b508060039081610050919061043f565b5061005f61006b60201b60201c565b5f81905550505061050e565b5f90565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6100ce82610088565b810181811067ffffffffffffffff821117156100ed576100ec610098565b5b80604052505050565b5f6100ff61006f565b905061010b82826100c5565b919050565b5f67ffffffffffffffff82111561012a57610129610098565b5b61013382610088565b9050602081019050919050565b8281835e5f83830152505050565b5f61016061015b84610110565b6100f6565b90508281526020810184848401111561017c5761017b610084565b5b610187848285610140565b509392505050565b5f82601f8301126101a3576101a2610080565b5b81516101b384826020860161014e565b91505092915050565b5f80604083850312156101d2576101d1610078565b5b5f83015167ffffffffffffffff8111156101ef576101ee61007c565b5b6101fb8582860161018f565b925050602083015167ffffffffffffffff81111561021c5761021b61007c565b5b6102288582860161018f565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061028057607f821691505b6020821081036102935761029261023c565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026102f57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102ba565b6102ff86836102ba565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61034361033e61033984610317565b610320565b610317565b9050919050565b5f819050919050565b61035c83610329565b6103706103688261034a565b8484546102c6565b825550505050565b5f90565b610384610378565b61038f818484610353565b505050565b5b818110156103b2576103a75f8261037c565b600181019050610395565b5050565b601f8211156103f7576103c881610299565b6103d1846102ab565b810160208510156103e0578190505b6103f46103ec856102ab565b830182610394565b50505b505050565b5f82821c905092915050565b5f6104175f19846008026103fc565b1980831691505092915050565b5f61042f8383610408565b9150826002028217905092915050565b61044882610232565b67ffffffffffffffff81111561046157610460610098565b5b61046b8254610269565b6104768282856103b6565b5f60209050601f8311600181146104a7575f8415610495578287015190505b61049f8582610424565b865550610506565b601f1984166104b586610299565b5f5b828110156104dc578489015182556001820191506020850194506020810190506104b7565b868310156104f957848901516104f5601f891682610408565b8355505b6001600288020188555050505b505050505050565b61199b8061051b5f395ff3fe608060405260043610610113575f3560e01c8063625553e21161009f578063a7cc013611610063578063a7cc0136146103a3578063b88d4fde146103df578063c87b56dd146103fb578063d9d21c6314610437578063e985e9c51461046157610113565b8063625553e2146102af5780636352211e146102d957806370a082311461031557806395d89b4114610351578063a22cb4651461037b57610113565b806318160ddd116100e657806318160ddd146101d557806323b872dd146101ff57806342842e0e1461021b578063444996c11461023757806347f69eba1461027357610113565b806301ffc9a71461011757806306fdde0314610153578063081812fc1461017d578063095ea7b3146101b9575b5f80fd5b348015610122575f80fd5b5061013d6004803603810190610138919061127b565b61049d565b60405161014a91906112c0565b60405180910390f35b34801561015e575f80fd5b5061016761052e565b6040516101749190611349565b60405180910390f35b348015610188575f80fd5b506101a3600480360381019061019e919061139c565b6105be565b6040516101b09190611406565b60405180910390f35b6101d360048036038101906101ce9190611449565b610617565b005b3480156101e0575f80fd5b506101e9610627565b6040516101f69190611496565b60405180910390f35b610219600480360381019061021491906114af565b61063c565b005b610235600480360381019061023091906114af565b6108e7565b005b348015610242575f80fd5b5061025d6004803603810190610258919061139c565b610906565b60405161026a9190611496565b60405180910390f35b34801561027e575f80fd5b506102996004803603810190610294919061139c565b6109e8565b6040516102a69190611496565b60405180910390f35b3480156102ba575f80fd5b506102c36109fd565b6040516102d09190611496565b60405180910390f35b3480156102e4575f80fd5b506102ff60048036038101906102fa919061139c565b610a1e565b60405161030c9190611406565b60405180910390f35b348015610320575f80fd5b5061033b600480360381019061033691906114ff565b610a2f565b6040516103489190611496565b60405180910390f35b34801561035c575f80fd5b50610365610ac3565b6040516103729190611349565b60405180910390f35b348015610386575f80fd5b506103a1600480360381019061039c9190611554565b610b53565b005b3480156103ae575f80fd5b506103c960048036038101906103c4919061139c565b610c59565b6040516103d69190611406565b60405180910390f35b6103f960048036038101906103f491906116be565b610c92565b005b348015610406575f80fd5b50610421600480360381019061041c919061139c565b610ce3565b60405161042e9190611349565b60405180910390f35b348015610442575f80fd5b5061044b610d5d565b6040516104589190611496565b60405180910390f35b34801561046c575f80fd5b506104876004803603810190610482919061173e565b610d7e565b60405161049491906112c0565b60405180910390f35b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104f757506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806105275750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461053d906117a9565b80601f0160208091040260200160405190810160405280929190818152602001828054610569906117a9565b80156105b45780601f1061058b576101008083540402835291602001916105b4565b820191905f5260205f20905b81548152906001019060200180831161059757829003601f168201915b5050505050905090565b5f6105c882610e0c565b6105dd576105dc63cf4700e460e01b610e7e565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61062382826001610e86565b5050565b5f610630610fb0565b6001545f540303905090565b5f61064682610906565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106bb576106ba63a114810060e01b610e7e565b5b5f806106c684610fb4565b915091506106dc81876106d7610fd7565b610fde565b610707576106f1866106ec610fd7565b610d7e565b610706576107056359c896be60e01b610e7e565b5b5b6107148686866001611021565b801561071e575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055506107e6856107c2888887611027565b7c02000000000000000000000000000000000000000000000000000000001761104e565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603610862575f6001850190505f60045f8381526020019081526020015f205403610860575f54811461085f578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036108d1576108d063ea553b3460e01b610e7e565b5b6108de8787876001611078565b50505050505050565b61090183838360405180602001604052805f815250610c92565b505050565b5f81610910610fb0565b116109d25760045f8381526020019081526020015f205490505f81036109aa575f5482106109495761094863df2d9b4260e01b610e7e565b5b5b60045f836001900393508381526020019081526020015f205490505f8103156109a5575f7c0100000000000000000000000000000000000000000000000000000000821603156109e3576109a463df2d9b4260e01b610e7e565b5b61094a565b5f7c0100000000000000000000000000000000000000000000000000000000821603156109e3575b6109e263df2d9b4260e01b610e7e565b5b919050565b6004602052805f5260405f205f915090505481565b7c020000000000000000000000000000000000000000000000000000000081565b5f610a2882610906565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610a7457610a73638f4eb60460e01b610e7e565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b606060038054610ad2906117a9565b80601f0160208091040260200160405190810160405280929190818152602001828054610afe906117a9565b8015610b495780601f10610b2057610100808354040283529160200191610b49565b820191905f5260205f20905b815481529060010190602001808311610b2c57829003601f168201915b5050505050905090565b8060075f610b5f610fd7565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610c08610fd7565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610c4d91906112c0565b60405180910390a35050565b6006602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b610c9d84848461063c565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14610cdd57610cc78484848461107e565b610cdc57610cdb63d1a57ed660e01b610e7e565b5b5b50505050565b6060610cee82610e0c565b610d0357610d0263a14c4b5060e01b610e7e565b5b5f610d0c6111a8565b90505f815103610d2a5760405180602001604052805f815250610d55565b80610d34846111be565b604051602001610d45929190611813565b6040516020818303038152906040525b915050919050565b7c010000000000000000000000000000000000000000000000000000000081565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f81610e16610fb0565b11610e79575f54821015610e78575f5b5f60045f8581526020019081526020015f205491508103610e525782610e4b90611863565b9250610e26565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b919050565b805f5260045ffd5b5f610e9083610a1e565b9050818015610ed257508073ffffffffffffffffffffffffffffffffffffffff16610eb9610fd7565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610efe57610ee881610ee3610fd7565b610d7e565b610efd57610efc63cfb3b94260e01b610e7e565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f90565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e861103d86868461120d565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a026110a3610fd7565b8786866040518563ffffffff1660e01b81526004016110c594939291906118dc565b6020604051808303815f875af192505050801561110057506040513d601f19601f820116820180604052508101906110fd919061193a565b60015b611155573d805f811461112e576040519150601f19603f3d011682016040523d82523d5f602084013e611133565b606091505b505f81510361114d5761114c63d1a57ed660e01b610e7e565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606060405180602001604052805f815250905090565b606060a060405101806040526020810391505f825281835b6001156111f857600184039350600a81066030018453600a81049050806111d6575b50828103602084039350808452505050919050565b5f9392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61125a81611226565b8114611264575f80fd5b50565b5f8135905061127581611251565b92915050565b5f602082840312156112905761128f61121e565b5b5f61129d84828501611267565b91505092915050565b5f8115159050919050565b6112ba816112a6565b82525050565b5f6020820190506112d35f8301846112b1565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61131b826112d9565b61132581856112e3565b93506113358185602086016112f3565b61133e81611301565b840191505092915050565b5f6020820190508181035f8301526113618184611311565b905092915050565b5f819050919050565b61137b81611369565b8114611385575f80fd5b50565b5f8135905061139681611372565b92915050565b5f602082840312156113b1576113b061121e565b5b5f6113be84828501611388565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6113f0826113c7565b9050919050565b611400816113e6565b82525050565b5f6020820190506114195f8301846113f7565b92915050565b611428816113e6565b8114611432575f80fd5b50565b5f813590506114438161141f565b92915050565b5f806040838503121561145f5761145e61121e565b5b5f61146c85828601611435565b925050602061147d85828601611388565b9150509250929050565b61149081611369565b82525050565b5f6020820190506114a95f830184611487565b92915050565b5f805f606084860312156114c6576114c561121e565b5b5f6114d386828701611435565b93505060206114e486828701611435565b92505060406114f586828701611388565b9150509250925092565b5f602082840312156115145761151361121e565b5b5f61152184828501611435565b91505092915050565b611533816112a6565b811461153d575f80fd5b50565b5f8135905061154e8161152a565b92915050565b5f806040838503121561156a5761156961121e565b5b5f61157785828601611435565b925050602061158885828601611540565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6115d082611301565b810181811067ffffffffffffffff821117156115ef576115ee61159a565b5b80604052505050565b5f611601611215565b905061160d82826115c7565b919050565b5f67ffffffffffffffff82111561162c5761162b61159a565b5b61163582611301565b9050602081019050919050565b828183375f83830152505050565b5f61166261165d84611612565b6115f8565b90508281526020810184848401111561167e5761167d611596565b5b611689848285611642565b509392505050565b5f82601f8301126116a5576116a4611592565b5b81356116b5848260208601611650565b91505092915050565b5f805f80608085870312156116d6576116d561121e565b5b5f6116e387828801611435565b94505060206116f487828801611435565b935050604061170587828801611388565b925050606085013567ffffffffffffffff81111561172657611725611222565b5b61173287828801611691565b91505092959194509250565b5f80604083850312156117545761175361121e565b5b5f61176185828601611435565b925050602061177285828601611435565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117c057607f821691505b6020821081036117d3576117d261177c565b5b50919050565b5f81905092915050565b5f6117ed826112d9565b6117f781856117d9565b93506118078185602086016112f3565b80840191505092915050565b5f61181e82856117e3565b915061182a82846117e3565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61186d82611369565b91505f820361187f5761187e611836565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6118ae8261188a565b6118b88185611894565b93506118c88185602086016112f3565b6118d181611301565b840191505092915050565b5f6080820190506118ef5f8301876113f7565b6118fc60208301866113f7565b6119096040830185611487565b818103606083015261191b81846118a4565b905095945050505050565b5f8151905061193481611251565b92915050565b5f6020828403121561194f5761194e61121e565b5b5f61195c84828501611926565b9150509291505056fea2646970667358221220e24466d9ba2a352bb6431f62f5c70c089d587006833991ec2a2117316da5741264736f6c63430008190033 \ No newline at end of file diff --git a/example/build/ERC721ATest.bin b/example/build/ERC721ATest.bin index 1ee5404..a39d2e7 100644 --- a/example/build/ERC721ATest.bin +++ b/example/build/ERC721ATest.bin @@ -1 +1 @@ -608060405234801562000010575f80fd5b5060405162003cd238038062003cd2833981810160405281019062000036919062000204565b81818160029081620000499190620004be565b5080600390816200005b9190620004be565b506200006c6200007b60201b60201c565b5f8190555050505050620005a2565b5f90565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620000e08262000098565b810181811067ffffffffffffffff82111715620001025762000101620000a8565b5b80604052505050565b5f620001166200007f565b9050620001248282620000d5565b919050565b5f67ffffffffffffffff821115620001465762000145620000a8565b5b620001518262000098565b9050602081019050919050565b5f5b838110156200017d57808201518184015260208101905062000160565b5f8484015250505050565b5f6200019e620001988462000129565b6200010b565b905082815260208101848484011115620001bd57620001bc62000094565b5b620001ca8482856200015e565b509392505050565b5f82601f830112620001e957620001e862000090565b5b8151620001fb84826020860162000188565b91505092915050565b5f80604083850312156200021d576200021c62000088565b5b5f83015167ffffffffffffffff8111156200023d576200023c6200008c565b5b6200024b85828601620001d2565b925050602083015167ffffffffffffffff8111156200026f576200026e6200008c565b5b6200027d85828601620001d2565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620002d657607f821691505b602082108103620002ec57620002eb62000291565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620003507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000313565b6200035c868362000313565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620003a6620003a06200039a8462000374565b6200037d565b62000374565b9050919050565b5f819050919050565b620003c18362000386565b620003d9620003d082620003ad565b8484546200031f565b825550505050565b5f90565b620003ef620003e1565b620003fc818484620003b6565b505050565b5b818110156200042357620004175f82620003e5565b60018101905062000402565b5050565b601f82111562000472576200043c81620002f2565b620004478462000304565b8101602085101562000457578190505b6200046f620004668562000304565b83018262000401565b50505b505050565b5f82821c905092915050565b5f620004945f198460080262000477565b1980831691505092915050565b5f620004ae838362000483565b9150826002028217905092915050565b620004c98262000287565b67ffffffffffffffff811115620004e557620004e4620000a8565b5b620004f18254620002be565b620004fe82828562000427565b5f60209050601f83116001811462000534575f84156200051f578287015190505b6200052b8582620004a1565b8655506200059a565b601f1984166200054486620002f2565b5f5b828110156200056d5784890151825560018201915060208501945060208101905062000546565b868310156200058d578489015162000589601f89168262000483565b8355505b6001600288020188555050505b505050505050565b61372280620005b05f395ff3fe6080604052600436106102c7575f3560e01c80638aa17d0f11610174578063beabacc8116100db578063e4c34fe011610094578063f5fad02a1161006e578063f5fad02a14610ad9578063f7950f8f14610b01578063fb42cf0f14610b29578063fe5ce8df14610b51576102c7565b8063e4c34fe014610a4d578063e985e9c514610a75578063f258def314610ab1576102c7565b8063beabacc814610933578063c03150081461095b578063c87b56dd14610983578063ccbf3ced146109bf578063d9d21c63146109e7578063db44fe0714610a11576102c7565b8063a29c4ae51161012d578063a29c4ae514610827578063a7cc01361461084f578063af77d5aa1461088b578063b79b6f13146108c7578063b88d4fde146108ef578063b97269201461090b576102c7565b80638aa17d0f146107215780638b0ce8b61461074957806395d89b411461077157806395ee293e1461079b5780639fccd9eb146107c3578063a22cb465146107ff576102c7565b806342842e0e11610233578063619f83b1116101ec57806370a08231116101c657806370a082311461066d5780637d1201e2146106a95780637e1d0f54146106d15780638249f3db146106f9576102c7565b8063619f83b1146105df578063625553e2146106075780636352211e14610631576102c7565b806342842e0e146104d357806342966c68146104ef578063444996c11461051757806347f69eba14610553578063487860ea1461058f5780635908e2ee146105b7576102c7565b806316fcf9651161028557806316fcf965146103d957806318160ddd1461040157806323b872dd1461042b578063276e334d1461044757806327ebe4771461046f57806340c10f19146104ab576102c7565b806213f201146102cb57806301ffc9a7146102f357806306fdde031461032f578063081812fc14610359578063095ea7b3146103955780630c7ef873146103b1575b5f80fd5b3480156102d6575f80fd5b506102f160048036038101906102ec9190612cc2565b610b8d565b005b3480156102fe575f80fd5b5061031960048036038101906103149190612d55565b610be7565b6040516103269190612d9a565b60405180910390f35b34801561033a575f80fd5b50610343610c78565b6040516103509190612e3d565b60405180910390f35b348015610364575f80fd5b5061037f600480360381019061037a9190612e5d565b610d08565b60405161038c9190612e97565b60405180910390f35b6103af60048036038101906103aa9190612cc2565b610d61565b005b3480156103bc575f80fd5b506103d760048036038101906103d29190612eb0565b610d71565b005b3480156103e4575f80fd5b506103ff60048036038101906103fa9190612f00565b610de2565b005b34801561040c575f80fd5b50610415610ed2565b6040516104229190612f4d565b60405180910390f35b61044560048036038101906104409190612eb0565b610ee7565b005b348015610452575f80fd5b5061046d60048036038101906104689190612e5d565b611192565b005b34801561047a575f80fd5b5061049560048036038101906104909190612e5d565b611213565b6040516104a29190612d9a565b60405180910390f35b3480156104b6575f80fd5b506104d160048036038101906104cc9190612cc2565b61123f565b005b6104ed60048036038101906104e89190612eb0565b61124d565b005b3480156104fa575f80fd5b5061051560048036038101906105109190612e5d565b61126c565b005b348015610522575f80fd5b5061053d60048036038101906105389190612e5d565b611279565b60405161054a9190612f4d565b60405180910390f35b34801561055e575f80fd5b5061057960048036038101906105749190612e5d565b61135b565b6040516105869190612f4d565b60405180910390f35b34801561059a575f80fd5b506105b560048036038101906105b09190612f66565b611370565b005b3480156105c2575f80fd5b506105dd60048036038101906105d89190612fca565b611464565b005b3480156105ea575f80fd5b5061060560048036038101906106009190612fca565b611480565b005b348015610612575f80fd5b5061061b61149c565b6040516106289190612f4d565b60405180910390f35b34801561063c575f80fd5b5061065760048036038101906106529190612e5d565b6114bd565b6040516106649190612e97565b60405180910390f35b348015610678575f80fd5b50610693600480360381019061068e9190613041565b6114ce565b6040516106a09190612f4d565b60405180910390f35b3480156106b4575f80fd5b506106cf60048036038101906106ca919061306c565b611562565b005b3480156106dc575f80fd5b506106f760048036038101906106f29190612fca565b6115d2565b005b348015610704575f80fd5b5061071f600480360381019061071a9190612eb0565b6115ee565b005b34801561072c575f80fd5b5061074760048036038101906107429190612cc2565b611626565b005b348015610754575f80fd5b5061076f600480360381019061076a91906130bc565b611692565b005b34801561077c575f80fd5b50610785611756565b6040516107929190612e3d565b60405180910390f35b3480156107a6575f80fd5b506107c160048036038101906107bc9190612cc2565b6117e6565b005b3480156107ce575f80fd5b506107e960048036038101906107e49190612e5d565b611864565b6040516107f69190612d9a565b60405180910390f35b34801561080a575f80fd5b5061082560048036038101906108209190613136565b611893565b005b348015610832575f80fd5b5061084d60048036038101906108489190612eb0565b611999565b005b34801561085a575f80fd5b5061087560048036038101906108709190612e5d565b611ab8565b6040516108829190612e97565b60405180910390f35b348015610896575f80fd5b506108b160048036038101906108ac9190612e5d565b611af1565b6040516108be9190612d9a565b60405180910390f35b3480156108d2575f80fd5b506108ed60048036038101906108e89190612eb0565b611b3f565b005b610909600480360381019061090491906132a0565b611baa565b005b348015610916575f80fd5b50610931600480360381019061092c9190612e5d565b611bfb565b005b34801561093e575f80fd5b5061095960048036038101906109549190612eb0565b611c2f565b005b348015610966575f80fd5b50610981600480360381019061097c9190613320565b611c3f565b005b34801561098e575f80fd5b506109a960048036038101906109a49190612e5d565b611cba565b6040516109b69190612e3d565b60405180910390f35b3480156109ca575f80fd5b506109e560048036038101906109e091906130bc565b611d34565b005b3480156109f2575f80fd5b506109fb611e2d565b604051610a089190612f4d565b60405180910390f35b348015610a1c575f80fd5b50610a376004803603810190610a329190612e5d565b611e4e565b604051610a449190612d9a565b60405180910390f35b348015610a58575f80fd5b50610a736004803603810190610a6e9190612fca565b611e81565b005b348015610a80575f80fd5b50610a9b6004803603810190610a96919061335e565b611e9d565b604051610aa89190612d9a565b60405180910390f35b348015610abc575f80fd5b50610ad76004803603810190610ad2919061339c565b611f2b565b005b348015610ae4575f80fd5b50610aff6004803603810190610afa9190612e5d565b611fd4565b005b348015610b0c575f80fd5b50610b276004803603810190610b229190612eb0565b61215f565b005b348015610b34575f80fd5b50610b4f6004803603810190610b4a9190612e5d565b612364565b005b348015610b5c575f80fd5b50610b776004803603810190610b729190612e5d565b6123c7565b604051610b849190612d9a565b60405180910390f35b610b97828261123f565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bd357610bd2613400565b5b5f8111610be357610be2613400565b5b5050565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c4157506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c715750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610c879061345a565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb39061345a565b8015610cfe5780601f10610cd557610100808354040283529160200191610cfe565b820191905f5260205f20905b815481529060010190602001808311610ce157829003601f168201915b5050505050905090565b5f610d1282612441565b610d2757610d2663cf4700e460e01b6124b3565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610d6d828260016124bb565b5050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610da8575f80fd5b5f610db2846114ce565b9050610dbf848484611c2f565b5f610dc9856114ce565b9050818114610ddb57610dda613400565b5b5050505050565b610deb82611864565b610df3575f80fd5b610dfc82611af1565b610e04575f80fd5b610e0d826123c7565b610e15575f80fd5b6bffffffffffffffffffffffff8016610e2c6125e5565b1115610e36575f80fd5b818103610e41575f80fd5b5f610e4b826114bd565b90505f610e5783611e4e565b9050610e628461126c565b5f610e6c846114bd565b90505f610e7885611e4e565b90508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610eb657610eb5613400565b5b82151581151514610eca57610ec9613400565b5b505050505050565b5f610edb6125ed565b6001545f540303905090565b5f610ef182611279565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f6657610f6563a114810060e01b6124b3565b5b5f80610f71846125f1565b91509150610f878187610f82612614565b61261b565b610fb257610f9c86610f97612614565b611e9d565b610fb157610fb06359c896be60e01b6124b3565b5b5b610fbf868686600161265e565b8015610fc9575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055506110918561106d888887612664565b7c02000000000000000000000000000000000000000000000000000000001761268b565b60045f8681526020019081526020015f20819055505f7c020000000000000000000000000000000000000000000000000000000084160361110d575f6001850190505f60045f8381526020019081526020015f20540361110b575f54811461110a578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f810361117c5761117b63ea553b3460e01b6124b3565b5b61118987878760016126b5565b50505050505050565b61119b81611213565b6111a3575f80fd5b6111ac81611864565b6111b4575f80fd5b5f6111be826114bd565b90505f6111ca826114ce565b90506111d58361126c565b5f6111df836114ce565b90508181106111f1576111f0613400565b5b6001826111fe91906134b7565b811461120d5761120c613400565b5b50505050565b5f61121d82612441565b158061123857505f611236611231846114bd565b6114ce565b115b9050919050565b61124982826126bb565b5050565b61126783838360405180602001604052805f815250611baa565b505050565b611276815f61280c565b50565b5f816112836125ed565b116113455760045f8381526020019081526020015f205490505f810361131d575f5482106112bc576112bb63df2d9b4260e01b6124b3565b5b5b60045f836001900393508381526020019081526020015f205490505f810315611318575f7c0100000000000000000000000000000000000000000000000000000000821603156113565761131763df2d9b4260e01b6124b3565b5b6112bd565b5f7c010000000000000000000000000000000000000000000000000000000082160315611356575b61135563df2d9b4260e01b6124b3565b5b919050565b6004602052805f5260405f205f915090505481565b61137982611864565b611381575f80fd5b61138a82611af1565b611392575f80fd5b61139b826123c7565b6113a3575f80fd5b6bffffffffffffffffffffffff80166113ba6125e5565b11156113c4575f80fd5b8181036113cf575f80fd5b5f6113d9826114bd565b90505f6113e583611e4e565b90506113f2868686611c2f565b5f6113fc846114bd565b90505f61140885611e4e565b90508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461144657611445613400565b5b8215158115151461145a57611459613400565b5b5050505050505050565b61147961147086611213565b85858585612a27565b5050505050565b61149561148c866123c7565b85858585612a27565b5050505050565b7c020000000000000000000000000000000000000000000000000000000081565b5f6114c782611279565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361151357611512638f4eb60460e01b6124b3565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611599575f80fd5b5f6115a3826114ce565b90506115af848461123f565b5f6115b9836114ce565b90508181146115cb576115ca613400565b5b5050505050565b6115e76115de86611af1565b85858585612a27565b5050505050565b5f6115f76125e5565b9050611604848484611c2f565b5f61160d6125e5565b905081811461161f5761161e613400565b5b5050505050565b5f61162f6125e5565b90506bffffffffffffffffffffffff801681111561164b575f80fd5b611655838361123f565b5f61165e6125e5565b90508181101561167157611670613400565b5b828261167d91906134ea565b811461168c5761168b613400565b5b50505050565b5f61169b6125e5565b90506bffffffffffffffffffffffff80168111156116b7575f80fd5b8082106116c2575f80fd5b5f6116cc836114bd565b90505f6116d884611e4e565b90506116e4868661123f565b5f6116ee856114bd565b90505f6116fa86611e4e565b90508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461173857611737613400565b5b8215158115151461174c5761174b613400565b5b5050505050505050565b6060600380546117659061345a565b80601f01602080910402602001604051908101604052809291908181526020018280546117919061345a565b80156117dc5780601f106117b3576101008083540402835291602001916117dc565b820191905f5260205f20905b8154815290600101906020018083116117bf57829003601f168201915b5050505050905090565b5f6117f0836114ce565b9050600267ffffffffffffffff611807919061355d565b67ffffffffffffffff1681111561181c575f80fd5b611826838361123f565b5f611830846114ce565b90508181101561184357611842613400565b5b828261184f91906134ea565b811461185e5761185d613400565b5b50505050565b5f8060045f8481526020019081526020015f20541415158061188c57506118896125e5565b82105b9050919050565b8060075f61189f612614565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611948612614565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161198d9190612d9a565b60405180910390a35050565b6119a281611213565b6119aa575f80fd5b6119b381611864565b6119bb575f80fd5b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036119f2575f80fd5b5f6119fc846114ce565b90505f611a08846114ce565b9050600267ffffffffffffffff611a1f919061355d565b67ffffffffffffffff16811115611a34575f80fd5b611a3f858585611c2f565b5f611a49866114ce565b90505f611a55866114ce565b9050838210611a6757611a66613400565b5b600184611a7491906134b7565b8214611a8357611a82613400565b5b828111611a9357611a92613400565b5b600183611aa091906134ea565b8114611aaf57611aae613400565b5b50505050505050565b6006602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b5f8060045f8481526020019081526020015f2054141580611b3857505f7c0200000000000000000000000000000000000000000000000000000000611b3584611279565b16145b9050919050565b611b4a838383611c2f565b8173ffffffffffffffffffffffffffffffffffffffff16611b6a826114bd565b73ffffffffffffffffffffffffffffffffffffffff1614611b8e57611b8d613400565b5b611b9781611e4e565b15611ba557611ba4613400565b5b505050565b611bb5848484610ee7565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14611bf557611bdf84848484612a7e565b611bf457611bf363d1a57ed660e01b6124b3565b5b5b50505050565b5f611c046125e5565b9050611c0f8261126c565b5f611c186125e5565b9050818114611c2a57611c29613400565b5b505050565b611c3a838383610ee7565b505050565b5f611c49836114bd565b90508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611c82575f80fd5b5f611c8c836114ce565b9050611c978461126c565b5f611ca1846114ce565b9050818114611cb357611cb2613400565b5b5050505050565b6060611cc582612441565b611cda57611cd963a14c4b5060e01b6124b3565b5b5f611ce3612ba8565b90505f815103611d015760405180602001604052805f815250611d2c565b80611d0b84612bbe565b604051602001611d1c9291906135c7565b6040516020818303038152906040525b915050919050565b5f611d3d6125e5565b90506bffffffffffffffffffffffff8016811115611d59575f80fd5b5f8190505b82811015611d8f575f60045f8381526020019081526020015f205414611d82575f80fd5b8080600101915050611d5e565b50611d9a848461123f565b5f611da36125e5565b9050808314611db0575f80fd5b5f8290505b81811015611e25578573ffffffffffffffffffffffffffffffffffffffff16611ddd826114bd565b73ffffffffffffffffffffffffffffffffffffffff1614611e0157611e00613400565b5b611e0a81611e4e565b15611e1857611e17613400565b5b8080600101915050611db5565b505050505050565b7c010000000000000000000000000000000000000000000000000000000081565b5f807c0100000000000000000000000000000000000000000000000000000000611e7784611279565b1614159050919050565b611e96611e8d86611864565b85858585612a27565b5050505050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f62575f80fd5b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f99575f80fd5b5f611fa3826114ce565b9050611fb0858585611c2f565b5f611fba836114ce565b9050818114611fcc57611fcb613400565b5b505050505050565b611fdd81611864565b611fe5575f80fd5b5f611fef82612441565b90505f611ffb83611e4e565b90505f612007846114bd565b90505f60065f8681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061207c575061207b8233611e9d565b5b905061208985600161280c565b8361209757612096613400565b5b82156120a6576120a5613400565b5b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806120dd5750805b6120ea576120e9613400565b5b5f73ffffffffffffffffffffffffffffffffffffffff1660065f8781526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461215857612157613400565b5b5050505050565b61216881611864565b612170575f80fd5b5f61217a82612441565b90505f61218683611e4e565b90505f612192846114bd565b90505f60065f8681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061220757506122068233611e9d565b5b9050612214878787611c2f565b8361222257612221613400565b5b821561223157612230613400565b5b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff160361226d5761226c613400565b5b8173ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16146122a9576122a8613400565b5b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806122e05750805b6122ed576122ec613400565b5b5f73ffffffffffffffffffffffffffffffffffffffff1660065f8781526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461235b5761235a613400565b5b50505050505050565b61236d8161126c565b61237681612441565b1561238457612383613400565b5b5f7c010000000000000000000000000000000000000000000000000000000060045f8481526020019081526020015f205416036123c4576123c3613400565b5b50565b5f807c02000000000000000000000000000000000000000000000000000000006123f084611279565b161415158061241257506124026125e5565b60018361240f91906134ea565b10155b8061243a57505f60045f60018561242991906134ea565b81526020019081526020015f205414155b9050919050565b5f8161244b6125ed565b116124ae575f548210156124ad575f5b5f60045f8581526020019081526020015f2054915081036124875782612480906135ea565b925061245b565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b919050565b805f5260045ffd5b5f6124c5836114bd565b905081801561250757508073ffffffffffffffffffffffffffffffffffffffff166124ee612614565b73ffffffffffffffffffffffffffffffffffffffff1614155b156125335761251d81612518612614565b611e9d565b6125325761253163cfb3b94260e01b6124b3565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f8054905090565b5f90565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e861267a868684612c0d565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f805490505f82036126d8576126d763b562e8dd60e01b6124b3565b5b6126e45f84838561265e565b612702836126f35f865f612664565b6126fc85612c15565b1761268b565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f81036127b3576127b2632e07630060e01b6124b3565b5b5f83830190505f8390505b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a48181600101915081036127be57815f819055505050506128075f8483856126b5565b505050565b5f61281683611279565b90505f8190505f80612827866125f1565b91509150841561286f57612843818461283e612614565b61261b565b61286e5761285883612853612614565b611e9d565b61286d5761286c6359c896be60e01b6124b3565b5b5b5b61287c835f88600161265e565b8015612886575f82555b600160806001901b0360055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254019250508190555061292a836128e7855f88612664565b7c02000000000000000000000000000000000000000000000000000000007c0100000000000000000000000000000000000000000000000000000000171761268b565b60045f8881526020019081526020015f20819055505f7c02000000000000000000000000000000000000000000000000000000008516036129a6575f6001870190505f60045f8381526020019081526020015f2054036129a4575f5481146129a3578460045f8381526020019081526020015f20819055505b5b505b855f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612a0e835f8860016126b5565b60015f8154809291906001019190505550505050505050565b84612a30575f80fd5b5f8103612a4657612a41848361123f565b612a69565b60018103612a5c57612a578261126c565b612a68565b612a67848484611c2f565b5b5b84612a7757612a76613400565b5b5050505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612aa3612614565b8786866040518563ffffffff1660e01b8152600401612ac59493929190613663565b6020604051808303815f875af1925050508015612b0057506040513d601f19601f82011682018060405250810190612afd91906136c1565b60015b612b55573d805f8114612b2e576040519150601f19603f3d011682016040523d82523d5f602084013e612b33565b606091505b505f815103612b4d57612b4c63d1a57ed660e01b6124b3565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606060405180602001604052805f815250905090565b606060a060405101806040526020810391505f825281835b600115612bf857600184039350600a81066030018453600a8104905080612bd6575b50828103602084039350808452505050919050565b5f9392505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612c5e82612c35565b9050919050565b612c6e81612c54565b8114612c78575f80fd5b50565b5f81359050612c8981612c65565b92915050565b5f819050919050565b612ca181612c8f565b8114612cab575f80fd5b50565b5f81359050612cbc81612c98565b92915050565b5f8060408385031215612cd857612cd7612c2d565b5b5f612ce585828601612c7b565b9250506020612cf685828601612cae565b9150509250929050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612d3481612d00565b8114612d3e575f80fd5b50565b5f81359050612d4f81612d2b565b92915050565b5f60208284031215612d6a57612d69612c2d565b5b5f612d7784828501612d41565b91505092915050565b5f8115159050919050565b612d9481612d80565b82525050565b5f602082019050612dad5f830184612d8b565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612dea578082015181840152602081019050612dcf565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612e0f82612db3565b612e198185612dbd565b9350612e29818560208601612dcd565b612e3281612df5565b840191505092915050565b5f6020820190508181035f830152612e558184612e05565b905092915050565b5f60208284031215612e7257612e71612c2d565b5b5f612e7f84828501612cae565b91505092915050565b612e9181612c54565b82525050565b5f602082019050612eaa5f830184612e88565b92915050565b5f805f60608486031215612ec757612ec6612c2d565b5b5f612ed486828701612c7b565b9350506020612ee586828701612c7b565b9250506040612ef686828701612cae565b9150509250925092565b5f8060408385031215612f1657612f15612c2d565b5b5f612f2385828601612cae565b9250506020612f3485828601612cae565b9150509250929050565b612f4781612c8f565b82525050565b5f602082019050612f605f830184612f3e565b92915050565b5f805f8060808587031215612f7e57612f7d612c2d565b5b5f612f8b87828801612c7b565b9450506020612f9c87828801612c7b565b9350506040612fad87828801612cae565b9250506060612fbe87828801612cae565b91505092959194509250565b5f805f805f60a08688031215612fe357612fe2612c2d565b5b5f612ff088828901612cae565b955050602061300188828901612c7b565b945050604061301288828901612c7b565b935050606061302388828901612cae565b925050608061303488828901612cae565b9150509295509295909350565b5f6020828403121561305657613055612c2d565b5b5f61306384828501612c7b565b91505092915050565b5f805f6060848603121561308357613082612c2d565b5b5f61309086828701612c7b565b93505060206130a186828701612cae565b92505060406130b286828701612c7b565b9150509250925092565b5f805f606084860312156130d3576130d2612c2d565b5b5f6130e086828701612c7b565b93505060206130f186828701612cae565b925050604061310286828701612cae565b9150509250925092565b61311581612d80565b811461311f575f80fd5b50565b5f813590506131308161310c565b92915050565b5f806040838503121561314c5761314b612c2d565b5b5f61315985828601612c7b565b925050602061316a85828601613122565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6131b282612df5565b810181811067ffffffffffffffff821117156131d1576131d061317c565b5b80604052505050565b5f6131e3612c24565b90506131ef82826131a9565b919050565b5f67ffffffffffffffff82111561320e5761320d61317c565b5b61321782612df5565b9050602081019050919050565b828183375f83830152505050565b5f61324461323f846131f4565b6131da565b9050828152602081018484840111156132605761325f613178565b5b61326b848285613224565b509392505050565b5f82601f83011261328757613286613174565b5b8135613297848260208601613232565b91505092915050565b5f805f80608085870312156132b8576132b7612c2d565b5b5f6132c587828801612c7b565b94505060206132d687828801612c7b565b93505060406132e787828801612cae565b925050606085013567ffffffffffffffff81111561330857613307612c31565b5b61331487828801613273565b91505092959194509250565b5f806040838503121561333657613335612c2d565b5b5f61334385828601612cae565b925050602061335485828601612c7b565b9150509250929050565b5f806040838503121561337457613373612c2d565b5b5f61338185828601612c7b565b925050602061339285828601612c7b565b9150509250929050565b5f805f80608085870312156133b4576133b3612c2d565b5b5f6133c187828801612c7b565b94505060206133d287828801612c7b565b93505060406133e387828801612cae565b92505060606133f487828801612c7b565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061347157607f821691505b6020821081036134845761348361342d565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6134c182612c8f565b91506134cc83612c8f565b92508282039050818111156134e4576134e361348a565b5b92915050565b5f6134f482612c8f565b91506134ff83612c8f565b92508282019050808211156135175761351661348a565b5b92915050565b5f67ffffffffffffffff82169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6135678261351d565b91506135728361351d565b92508261358257613581613530565b5b828204905092915050565b5f81905092915050565b5f6135a182612db3565b6135ab818561358d565b93506135bb818560208601612dcd565b80840191505092915050565b5f6135d28285613597565b91506135de8284613597565b91508190509392505050565b5f6135f482612c8f565b91505f82036136065761360561348a565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f61363582613611565b61363f818561361b565b935061364f818560208601612dcd565b61365881612df5565b840191505092915050565b5f6080820190506136765f830187612e88565b6136836020830186612e88565b6136906040830185612f3e565b81810360608301526136a2818461362b565b905095945050505050565b5f815190506136bb81612d2b565b92915050565b5f602082840312156136d6576136d5612c2d565b5b5f6136e3848285016136ad565b9150509291505056fea26469706673582212207ddf3dd23f5c0968a25e21e77ded1fe1a57071193cb85ca7f0394553fcbfc7a064736f6c63430008180033 \ No newline at end of file +608060405234801561000f575f80fd5b50604051613c9e380380613c9e833981810160405281019061003191906101c0565b818181600290816100429190610443565b5080600390816100529190610443565b5061006161006f60201b60201c565b5f8190555050505050610512565b5f90565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6100d28261008c565b810181811067ffffffffffffffff821117156100f1576100f061009c565b5b80604052505050565b5f610103610073565b905061010f82826100c9565b919050565b5f67ffffffffffffffff82111561012e5761012d61009c565b5b6101378261008c565b9050602081019050919050565b8281835e5f83830152505050565b5f61016461015f84610114565b6100fa565b9050828152602081018484840111156101805761017f610088565b5b61018b848285610144565b509392505050565b5f82601f8301126101a7576101a6610084565b5b81516101b7848260208601610152565b91505092915050565b5f80604083850312156101d6576101d561007c565b5b5f83015167ffffffffffffffff8111156101f3576101f2610080565b5b6101ff85828601610193565b925050602083015167ffffffffffffffff8111156102205761021f610080565b5b61022c85828601610193565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061028457607f821691505b60208210810361029757610296610240565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026102f97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102be565b61030386836102be565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61034761034261033d8461031b565b610324565b61031b565b9050919050565b5f819050919050565b6103608361032d565b61037461036c8261034e565b8484546102ca565b825550505050565b5f90565b61038861037c565b610393818484610357565b505050565b5b818110156103b6576103ab5f82610380565b600181019050610399565b5050565b601f8211156103fb576103cc8161029d565b6103d5846102af565b810160208510156103e4578190505b6103f86103f0856102af565b830182610398565b50505b505050565b5f82821c905092915050565b5f61041b5f1984600802610400565b1980831691505092915050565b5f610433838361040c565b9150826002028217905092915050565b61044c82610236565b67ffffffffffffffff8111156104655761046461009c565b5b61046f825461026d565b61047a8282856103ba565b5f60209050601f8311600181146104ab575f8415610499578287015190505b6104a38582610428565b86555061050a565b601f1984166104b98661029d565b5f5b828110156104e0578489015182556001820191506020850194506020810190506104bb565b868310156104fd57848901516104f9601f89168261040c565b8355505b6001600288020188555050505b505050505050565b61377f8061051f5f395ff3fe6080604052600436106102c7575f3560e01c80638aa17d0f11610174578063beabacc8116100db578063e4c34fe011610094578063f5fad02a1161006e578063f5fad02a14610ad9578063f7950f8f14610b01578063fb42cf0f14610b29578063fe5ce8df14610b51576102c7565b8063e4c34fe014610a4d578063e985e9c514610a75578063f258def314610ab1576102c7565b8063beabacc814610933578063c03150081461095b578063c87b56dd14610983578063ccbf3ced146109bf578063d9d21c63146109e7578063db44fe0714610a11576102c7565b8063a29c4ae51161012d578063a29c4ae514610827578063a7cc01361461084f578063af77d5aa1461088b578063b79b6f13146108c7578063b88d4fde146108ef578063b97269201461090b576102c7565b80638aa17d0f146107215780638b0ce8b61461074957806395d89b411461077157806395ee293e1461079b5780639fccd9eb146107c3578063a22cb465146107ff576102c7565b806342842e0e11610233578063619f83b1116101ec57806370a08231116101c657806370a082311461066d5780637d1201e2146106a95780637e1d0f54146106d15780638249f3db146106f9576102c7565b8063619f83b1146105df578063625553e2146106075780636352211e14610631576102c7565b806342842e0e146104d357806342966c68146104ef578063444996c11461051757806347f69eba14610553578063487860ea1461058f5780635908e2ee146105b7576102c7565b806316fcf9651161028557806316fcf965146103d957806318160ddd1461040157806323b872dd1461042b578063276e334d1461044757806327ebe4771461046f57806340c10f19146104ab576102c7565b806213f201146102cb57806301ffc9a7146102f357806306fdde031461032f578063081812fc14610359578063095ea7b3146103955780630c7ef873146103b1575b5f80fd5b3480156102d6575f80fd5b506102f160048036038101906102ec9190612d39565b610b8d565b005b3480156102fe575f80fd5b5061031960048036038101906103149190612dcc565b610bdc565b6040516103269190612e11565b60405180910390f35b34801561033a575f80fd5b50610343610c6d565b6040516103509190612e9a565b60405180910390f35b348015610364575f80fd5b5061037f600480360381019061037a9190612eba565b610cfd565b60405161038c9190612ef4565b60405180910390f35b6103af60048036038101906103aa9190612d39565b610d56565b005b3480156103bc575f80fd5b506103d760048036038101906103d29190612f0d565b610d66565b005b3480156103e4575f80fd5b506103ff60048036038101906103fa9190612f5d565b610dd7565b005b34801561040c575f80fd5b50610415610ec7565b6040516104229190612faa565b60405180910390f35b61044560048036038101906104409190612f0d565b610edc565b005b348015610452575f80fd5b5061046d60048036038101906104689190612eba565b611187565b005b34801561047a575f80fd5b5061049560048036038101906104909190612eba565b611208565b6040516104a29190612e11565b60405180910390f35b3480156104b6575f80fd5b506104d160048036038101906104cc9190612d39565b611234565b005b6104ed60048036038101906104e89190612f0d565b611242565b005b3480156104fa575f80fd5b5061051560048036038101906105109190612eba565b611261565b005b348015610522575f80fd5b5061053d60048036038101906105389190612eba565b61126e565b60405161054a9190612faa565b60405180910390f35b34801561055e575f80fd5b5061057960048036038101906105749190612eba565b611350565b6040516105869190612faa565b60405180910390f35b34801561059a575f80fd5b506105b560048036038101906105b09190612fc3565b611365565b005b3480156105c2575f80fd5b506105dd60048036038101906105d89190613027565b611459565b005b3480156105ea575f80fd5b5061060560048036038101906106009190613027565b611475565b005b348015610612575f80fd5b5061061b611491565b6040516106289190612faa565b60405180910390f35b34801561063c575f80fd5b5061065760048036038101906106529190612eba565b6114b2565b6040516106649190612ef4565b60405180910390f35b348015610678575f80fd5b50610693600480360381019061068e919061309e565b6114c3565b6040516106a09190612faa565b60405180910390f35b3480156106b4575f80fd5b506106cf60048036038101906106ca91906130c9565b611557565b005b3480156106dc575f80fd5b506106f760048036038101906106f29190613027565b6115c7565b005b348015610704575f80fd5b5061071f600480360381019061071a9190612f0d565b6115e3565b005b34801561072c575f80fd5b5061074760048036038101906107429190612d39565b61161b565b005b348015610754575f80fd5b5061076f600480360381019061076a9190613119565b6116c8565b005b34801561077c575f80fd5b5061078561178c565b6040516107929190612e9a565b60405180910390f35b3480156107a6575f80fd5b506107c160048036038101906107bc9190612d39565b61181c565b005b3480156107ce575f80fd5b506107e960048036038101906107e49190612eba565b6118db565b6040516107f69190612e11565b60405180910390f35b34801561080a575f80fd5b5061082560048036038101906108209190613193565b61190a565b005b348015610832575f80fd5b5061084d60048036038101906108489190612f0d565b611a10565b005b34801561085a575f80fd5b5061087560048036038101906108709190612eba565b611b2f565b6040516108829190612ef4565b60405180910390f35b348015610896575f80fd5b506108b160048036038101906108ac9190612eba565b611b68565b6040516108be9190612e11565b60405180910390f35b3480156108d2575f80fd5b506108ed60048036038101906108e89190612f0d565b611bb6565b005b610909600480360381019061090491906132fd565b611c21565b005b348015610916575f80fd5b50610931600480360381019061092c9190612eba565b611c72565b005b34801561093e575f80fd5b5061095960048036038101906109549190612f0d565b611ca6565b005b348015610966575f80fd5b50610981600480360381019061097c919061337d565b611cb6565b005b34801561098e575f80fd5b506109a960048036038101906109a49190612eba565b611d31565b6040516109b69190612e9a565b60405180910390f35b3480156109ca575f80fd5b506109e560048036038101906109e09190613119565b611dab565b005b3480156109f2575f80fd5b506109fb611ea4565b604051610a089190612faa565b60405180910390f35b348015610a1c575f80fd5b50610a376004803603810190610a329190612eba565b611ec5565b604051610a449190612e11565b60405180910390f35b348015610a58575f80fd5b50610a736004803603810190610a6e9190613027565b611ef8565b005b348015610a80575f80fd5b50610a9b6004803603810190610a9691906133bb565b611f14565b604051610aa89190612e11565b60405180910390f35b348015610abc575f80fd5b50610ad76004803603810190610ad291906133f9565b611fa2565b005b348015610ae4575f80fd5b50610aff6004803603810190610afa9190612eba565b61204b565b005b348015610b0c575f80fd5b50610b276004803603810190610b229190612f0d565b6121d6565b005b348015610b34575f80fd5b50610b4f6004803603810190610b4a9190612eba565b6123db565b005b348015610b5c575f80fd5b50610b776004803603810190610b729190612eba565b61243e565b604051610b849190612e11565b60405180910390f35b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015610bc857505f81115b15610bd857610bd78282611234565b5b5050565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c3657506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610c665750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610c7c9061348a565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca89061348a565b8015610cf35780601f10610cca57610100808354040283529160200191610cf3565b820191905f5260205f20905b815481529060010190602001808311610cd657829003601f168201915b5050505050905090565b5f610d07826124b8565b610d1c57610d1b63cf4700e460e01b61252a565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610d6282826001612532565b5050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610d9d575f80fd5b5f610da7846114c3565b9050610db4848484611ca6565b5f610dbe856114c3565b9050818114610dd057610dcf6134ba565b5b5050505050565b610de0826118db565b610de8575f80fd5b610df182611b68565b610df9575f80fd5b610e028261243e565b610e0a575f80fd5b6bffffffffffffffffffffffff8016610e2161265c565b1115610e2b575f80fd5b818103610e36575f80fd5b5f610e40826114b2565b90505f610e4c83611ec5565b9050610e5784611261565b5f610e61846114b2565b90505f610e6d85611ec5565b90508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610eab57610eaa6134ba565b5b82151581151514610ebf57610ebe6134ba565b5b505050505050565b5f610ed0612664565b6001545f540303905090565b5f610ee68261126e565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f5b57610f5a63a114810060e01b61252a565b5b5f80610f6684612668565b91509150610f7c8187610f7761268b565b612692565b610fa757610f9186610f8c61268b565b611f14565b610fa657610fa56359c896be60e01b61252a565b5b5b610fb486868660016126d5565b8015610fbe575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815460010191905081905550611086856110628888876126db565b7c020000000000000000000000000000000000000000000000000000000017612702565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603611102575f6001850190505f60045f8381526020019081526020015f205403611100575f5481146110ff578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036111715761117063ea553b3460e01b61252a565b5b61117e878787600161272c565b50505050505050565b61119081611208565b611198575f80fd5b6111a1816118db565b6111a9575f80fd5b5f6111b3826114b2565b90505f6111bf826114c3565b90506111ca83611261565b5f6111d4836114c3565b90508181106111e6576111e56134ba565b5b6001826111f39190613514565b8114611202576112016134ba565b5b50505050565b5f611212826124b8565b158061122d57505f61122b611226846114b2565b6114c3565b115b9050919050565b61123e8282612732565b5050565b61125c83838360405180602001604052805f815250611c21565b505050565b61126b815f612883565b50565b5f81611278612664565b1161133a5760045f8381526020019081526020015f205490505f8103611312575f5482106112b1576112b063df2d9b4260e01b61252a565b5b5b60045f836001900393508381526020019081526020015f205490505f81031561130d575f7c01000000000000000000000000000000000000000000000000000000008216031561134b5761130c63df2d9b4260e01b61252a565b5b6112b2565b5f7c01000000000000000000000000000000000000000000000000000000008216031561134b575b61134a63df2d9b4260e01b61252a565b5b919050565b6004602052805f5260405f205f915090505481565b61136e826118db565b611376575f80fd5b61137f82611b68565b611387575f80fd5b6113908261243e565b611398575f80fd5b6bffffffffffffffffffffffff80166113af61265c565b11156113b9575f80fd5b8181036113c4575f80fd5b5f6113ce826114b2565b90505f6113da83611ec5565b90506113e7868686611ca6565b5f6113f1846114b2565b90505f6113fd85611ec5565b90508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461143b5761143a6134ba565b5b8215158115151461144f5761144e6134ba565b5b5050505050505050565b61146e61146586611208565b85858585612a9e565b5050505050565b61148a6114818661243e565b85858585612a9e565b5050505050565b7c020000000000000000000000000000000000000000000000000000000081565b5f6114bc8261126e565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361150857611507638f4eb60460e01b61252a565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361158e575f80fd5b5f611598826114c3565b90506115a48484611234565b5f6115ae836114c3565b90508181146115c0576115bf6134ba565b5b5050505050565b6115dc6115d386611b68565b85858585612a9e565b5050505050565b5f6115ec61265c565b90506115f9848484611ca6565b5f61160261265c565b9050818114611614576116136134ba565b5b5050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561165657505f81115b156116c4575f61166461265c565b90506bffffffffffffffffffffffff8016811115611680575f80fd5b61168a8383611234565b5f61169361265c565b9050818110156116a6576116a56134ba565b5b82826116b29190613547565b81146116c1576116c06134ba565b5b50505b5050565b5f6116d161265c565b90506bffffffffffffffffffffffff80168111156116ed575f80fd5b8082106116f8575f80fd5b5f611702836114b2565b90505f61170e84611ec5565b905061171a8686611234565b5f611724856114b2565b90505f61173086611ec5565b90508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461176e5761176d6134ba565b5b82151581151514611782576117816134ba565b5b5050505050505050565b60606003805461179b9061348a565b80601f01602080910402602001604051908101604052809291908181526020018280546117c79061348a565b80156118125780601f106117e957610100808354040283529160200191611812565b820191905f5260205f20905b8154815290600101906020018083116117f557829003601f168201915b5050505050905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561185757505f81115b156118d7575f611866836114c3565b9050600267ffffffffffffffff61187d91906135ba565b67ffffffffffffffff16811115611892575f80fd5b61189c8383611234565b5f6118a6846114c3565b9050818110156118b9576118b86134ba565b5b82826118c59190613547565b81146118d4576118d36134ba565b5b50505b5050565b5f8060045f8481526020019081526020015f205414151580611903575061190061265c565b82105b9050919050565b8060075f61191661268b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166119bf61268b565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611a049190612e11565b60405180910390a35050565b611a1981611208565b611a21575f80fd5b611a2a816118db565b611a32575f80fd5b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611a69575f80fd5b5f611a73846114c3565b90505f611a7f846114c3565b9050600267ffffffffffffffff611a9691906135ba565b67ffffffffffffffff16811115611aab575f80fd5b611ab6858585611ca6565b5f611ac0866114c3565b90505f611acc866114c3565b9050838210611ade57611add6134ba565b5b600184611aeb9190613514565b8214611afa57611af96134ba565b5b828111611b0a57611b096134ba565b5b600183611b179190613547565b8114611b2657611b256134ba565b5b50505050505050565b6006602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b5f8060045f8481526020019081526020015f2054141580611baf57505f7c0200000000000000000000000000000000000000000000000000000000611bac8461126e565b16145b9050919050565b611bc1838383611ca6565b8173ffffffffffffffffffffffffffffffffffffffff16611be1826114b2565b73ffffffffffffffffffffffffffffffffffffffff1614611c0557611c046134ba565b5b611c0e81611ec5565b15611c1c57611c1b6134ba565b5b505050565b611c2c848484610edc565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14611c6c57611c5684848484612af5565b611c6b57611c6a63d1a57ed660e01b61252a565b5b5b50505050565b5f611c7b61265c565b9050611c8682611261565b5f611c8f61265c565b9050818114611ca157611ca06134ba565b5b505050565b611cb1838383610edc565b505050565b5f611cc0836114b2565b90508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611cf9575f80fd5b5f611d03836114c3565b9050611d0e84611261565b5f611d18846114c3565b9050818114611d2a57611d296134ba565b5b5050505050565b6060611d3c826124b8565b611d5157611d5063a14c4b5060e01b61252a565b5b5f611d5a612c1f565b90505f815103611d785760405180602001604052805f815250611da3565b80611d8284612c35565b604051602001611d93929190613624565b6040516020818303038152906040525b915050919050565b5f611db461265c565b90506bffffffffffffffffffffffff8016811115611dd0575f80fd5b5f8190505b82811015611e06575f60045f8381526020019081526020015f205414611df9575f80fd5b8080600101915050611dd5565b50611e118484611234565b5f611e1a61265c565b9050808314611e27575f80fd5b5f8290505b81811015611e9c578573ffffffffffffffffffffffffffffffffffffffff16611e54826114b2565b73ffffffffffffffffffffffffffffffffffffffff1614611e7857611e776134ba565b5b611e8181611ec5565b15611e8f57611e8e6134ba565b5b8080600101915050611e2c565b505050505050565b7c010000000000000000000000000000000000000000000000000000000081565b5f807c0100000000000000000000000000000000000000000000000000000000611eee8461126e565b1614159050919050565b611f0d611f04866118db565b85858585612a9e565b5050505050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611fd9575f80fd5b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612010575f80fd5b5f61201a826114c3565b9050612027858585611ca6565b5f612031836114c3565b9050818114612043576120426134ba565b5b505050505050565b612054816118db565b61205c575f80fd5b5f612066826124b8565b90505f61207283611ec5565b90505f61207e846114b2565b90505f60065f8681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806120f357506120f28233611f14565b5b9050612100856001612883565b8361210e5761210d6134ba565b5b821561211d5761211c6134ba565b5b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806121545750805b612161576121606134ba565b5b5f73ffffffffffffffffffffffffffffffffffffffff1660065f8781526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146121cf576121ce6134ba565b5b5050505050565b6121df816118db565b6121e7575f80fd5b5f6121f1826124b8565b90505f6121fd83611ec5565b90505f612209846114b2565b90505f60065f8681526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061227e575061227d8233611f14565b5b905061228b878787611ca6565b83612299576122986134ba565b5b82156122a8576122a76134ba565b5b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036122e4576122e36134ba565b5b8173ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16146123205761231f6134ba565b5b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806123575750805b612364576123636134ba565b5b5f73ffffffffffffffffffffffffffffffffffffffff1660065f8781526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146123d2576123d16134ba565b5b50505050505050565b6123e481611261565b6123ed816124b8565b156123fb576123fa6134ba565b5b5f7c010000000000000000000000000000000000000000000000000000000060045f8481526020019081526020015f2054160361243b5761243a6134ba565b5b50565b5f807c02000000000000000000000000000000000000000000000000000000006124678461126e565b1614151580612489575061247961265c565b6001836124869190613547565b10155b806124b157505f60045f6001856124a09190613547565b81526020019081526020015f205414155b9050919050565b5f816124c2612664565b11612525575f54821015612524575f5b5f60045f8581526020019081526020015f2054915081036124fe57826124f790613647565b92506124d2565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b919050565b805f5260045ffd5b5f61253c836114b2565b905081801561257e57508073ffffffffffffffffffffffffffffffffffffffff1661256561268b565b73ffffffffffffffffffffffffffffffffffffffff1614155b156125aa576125948161258f61268b565b611f14565b6125a9576125a863cfb3b94260e01b61252a565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f8054905090565b5f90565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e86126f1868684612c84565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f805490505f820361274f5761274e63b562e8dd60e01b61252a565b5b61275b5f8483856126d5565b6127798361276a5f865f6126db565b61277385612c8c565b17612702565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f810361282a57612829632e07630060e01b61252a565b5b5f83830190505f8390505b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a481816001019150810361283557815f8190555050505061287e5f84838561272c565b505050565b5f61288d8361126e565b90505f8190505f8061289e86612668565b9150915084156128e6576128ba81846128b561268b565b612692565b6128e5576128cf836128ca61268b565b611f14565b6128e4576128e36359c896be60e01b61252a565b5b5b5b6128f3835f8860016126d5565b80156128fd575f82555b600160806001901b0360055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055506129a18361295e855f886126db565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717612702565b60045f8881526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000851603612a1d575f6001870190505f60045f8381526020019081526020015f205403612a1b575f548114612a1a578460045f8381526020019081526020015f20819055505b5b505b855f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612a85835f88600161272c565b60015f8154809291906001019190505550505050505050565b84612aa7575f80fd5b5f8103612abd57612ab88483611234565b612ae0565b60018103612ad357612ace82611261565b612adf565b612ade848484611ca6565b5b5b84612aee57612aed6134ba565b5b5050505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612b1a61268b565b8786866040518563ffffffff1660e01b8152600401612b3c94939291906136c0565b6020604051808303815f875af1925050508015612b7757506040513d601f19601f82011682018060405250810190612b74919061371e565b60015b612bcc573d805f8114612ba5576040519150601f19603f3d011682016040523d82523d5f602084013e612baa565b606091505b505f815103612bc457612bc363d1a57ed660e01b61252a565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606060405180602001604052805f815250905090565b606060a060405101806040526020810391505f825281835b600115612c6f57600184039350600a81066030018453600a8104905080612c4d575b50828103602084039350808452505050919050565b5f9392505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612cd582612cac565b9050919050565b612ce581612ccb565b8114612cef575f80fd5b50565b5f81359050612d0081612cdc565b92915050565b5f819050919050565b612d1881612d06565b8114612d22575f80fd5b50565b5f81359050612d3381612d0f565b92915050565b5f8060408385031215612d4f57612d4e612ca4565b5b5f612d5c85828601612cf2565b9250506020612d6d85828601612d25565b9150509250929050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612dab81612d77565b8114612db5575f80fd5b50565b5f81359050612dc681612da2565b92915050565b5f60208284031215612de157612de0612ca4565b5b5f612dee84828501612db8565b91505092915050565b5f8115159050919050565b612e0b81612df7565b82525050565b5f602082019050612e245f830184612e02565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612e6c82612e2a565b612e768185612e34565b9350612e86818560208601612e44565b612e8f81612e52565b840191505092915050565b5f6020820190508181035f830152612eb28184612e62565b905092915050565b5f60208284031215612ecf57612ece612ca4565b5b5f612edc84828501612d25565b91505092915050565b612eee81612ccb565b82525050565b5f602082019050612f075f830184612ee5565b92915050565b5f805f60608486031215612f2457612f23612ca4565b5b5f612f3186828701612cf2565b9350506020612f4286828701612cf2565b9250506040612f5386828701612d25565b9150509250925092565b5f8060408385031215612f7357612f72612ca4565b5b5f612f8085828601612d25565b9250506020612f9185828601612d25565b9150509250929050565b612fa481612d06565b82525050565b5f602082019050612fbd5f830184612f9b565b92915050565b5f805f8060808587031215612fdb57612fda612ca4565b5b5f612fe887828801612cf2565b9450506020612ff987828801612cf2565b935050604061300a87828801612d25565b925050606061301b87828801612d25565b91505092959194509250565b5f805f805f60a086880312156130405761303f612ca4565b5b5f61304d88828901612d25565b955050602061305e88828901612cf2565b945050604061306f88828901612cf2565b935050606061308088828901612d25565b925050608061309188828901612d25565b9150509295509295909350565b5f602082840312156130b3576130b2612ca4565b5b5f6130c084828501612cf2565b91505092915050565b5f805f606084860312156130e0576130df612ca4565b5b5f6130ed86828701612cf2565b93505060206130fe86828701612d25565b925050604061310f86828701612cf2565b9150509250925092565b5f805f606084860312156131305761312f612ca4565b5b5f61313d86828701612cf2565b935050602061314e86828701612d25565b925050604061315f86828701612d25565b9150509250925092565b61317281612df7565b811461317c575f80fd5b50565b5f8135905061318d81613169565b92915050565b5f80604083850312156131a9576131a8612ca4565b5b5f6131b685828601612cf2565b92505060206131c78582860161317f565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61320f82612e52565b810181811067ffffffffffffffff8211171561322e5761322d6131d9565b5b80604052505050565b5f613240612c9b565b905061324c8282613206565b919050565b5f67ffffffffffffffff82111561326b5761326a6131d9565b5b61327482612e52565b9050602081019050919050565b828183375f83830152505050565b5f6132a161329c84613251565b613237565b9050828152602081018484840111156132bd576132bc6131d5565b5b6132c8848285613281565b509392505050565b5f82601f8301126132e4576132e36131d1565b5b81356132f484826020860161328f565b91505092915050565b5f805f806080858703121561331557613314612ca4565b5b5f61332287828801612cf2565b945050602061333387828801612cf2565b935050604061334487828801612d25565b925050606085013567ffffffffffffffff81111561336557613364612ca8565b5b613371878288016132d0565b91505092959194509250565b5f806040838503121561339357613392612ca4565b5b5f6133a085828601612d25565b92505060206133b185828601612cf2565b9150509250929050565b5f80604083850312156133d1576133d0612ca4565b5b5f6133de85828601612cf2565b92505060206133ef85828601612cf2565b9150509250929050565b5f805f806080858703121561341157613410612ca4565b5b5f61341e87828801612cf2565b945050602061342f87828801612cf2565b935050604061344087828801612d25565b925050606061345187828801612cf2565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806134a157607f821691505b6020821081036134b4576134b361345d565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61351e82612d06565b915061352983612d06565b9250828203905081811115613541576135406134e7565b5b92915050565b5f61355182612d06565b915061355c83612d06565b9250828201905080821115613574576135736134e7565b5b92915050565b5f67ffffffffffffffff82169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6135c48261357a565b91506135cf8361357a565b9250826135df576135de61358d565b5b828204905092915050565b5f81905092915050565b5f6135fe82612e2a565b61360881856135ea565b9350613618818560208601612e44565b80840191505092915050565b5f61362f82856135f4565b915061363b82846135f4565b91508190509392505050565b5f61365182612d06565b91505f8203613663576136626134e7565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6136928261366e565b61369c8185613678565b93506136ac818560208601612e44565b6136b581612e52565b840191505092915050565b5f6080820190506136d35f830187612ee5565b6136e06020830186612ee5565b6136ed6040830185612f9b565b81810360608301526136ff8184613688565b905095945050505050565b5f8151905061371881612da2565b92915050565b5f6020828403121561373357613732612ca4565b5b5f6137408482850161370a565b9150509291505056fea2646970667358221220024dbbf480875fa8b069eb012d4b3585b1fc7c5c6c7dc05062499b2ccb17136f64736f6c63430008190033 \ No newline at end of file diff --git a/example/build/SimpleContract.bin b/example/build/SimpleContract.bin index cace318..f7c6f15 100644 --- a/example/build/SimpleContract.bin +++ b/example/build/SimpleContract.bin @@ -1 +1 @@ -608060405234801561000f575f80fd5b506101f58061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063c5eb648f1461002d575b5f80fd5b610047600480360381019061004291906100f0565b610049565b005b5f8263ffffffff16118015610064575060648263ffffffff16105b801561007557505f8163ffffffff16115b8015610087575060648163ffffffff16105b156100af57608e818361009a919061015b565b63ffffffff16036100ae576100ad610192565b5b5b5050565b5f80fd5b5f63ffffffff82169050919050565b6100cf816100b7565b81146100d9575f80fd5b50565b5f813590506100ea816100c6565b92915050565b5f8060408385031215610106576101056100b3565b5b5f610113858286016100dc565b9250506020610124858286016100dc565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610165826100b7565b9150610170836100b7565b9250828201905063ffffffff81111561018c5761018b61012e565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffdfea2646970667358221220a39c51491088ffef55d73d836a5e82f6f2ddd811d09d15817259da0ab8114d9264736f6c63430008180033 \ No newline at end of file +6080604052348015600e575f80fd5b506101b18061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063c5eb648f1461002d575b5f80fd5b610047600480360381019061004291906100ac565b610049565b005b608e81836100579190610117565b63ffffffff160361006b5761006a61014e565b5b5050565b5f80fd5b5f63ffffffff82169050919050565b61008b81610073565b8114610095575f80fd5b50565b5f813590506100a681610082565b92915050565b5f80604083850312156100c2576100c161006f565b5b5f6100cf85828601610098565b92505060206100e085828601610098565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61012182610073565b915061012c83610073565b9250828201905063ffffffff811115610148576101476100ea565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffdfea2646970667358221220b1927f8ca246d643c2c1b152b3f5e93b02491ed08c60d3fe057dea580cc74ea264736f6c63430008190033 \ No newline at end of file diff --git a/example/simple.sol b/example/simple.sol index 9182fa5..85f206f 100644 --- a/example/simple.sol +++ b/example/simple.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; contract SimpleContract { function check(uint32 x, uint32 y) public pure { - if (x > 0 && x < 100 && y > 0 && y < 100) { - assert(x + y != 142); - } + //if (x > 0 && x < 100 && y > 0 && y < 100) { + assert(x + y != 142); + //} } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c15bfa9..d2224bd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use env_logger; use getopts::Options; use log::{debug, error, info, warn}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::error::Error; use std::fs::File; use std::io::Read; @@ -9,14 +9,20 @@ use std::time; use std::{env, process}; use tokio::task; -use rhoevm::modules::abi::{AbiType, Sig}; +use rhoevm::modules::abi::{selector, AbiType, Sig}; use rhoevm::modules::cli::{build_calldata, vm0, SymbolicCommand}; use rhoevm::modules::evm::{abstract_contract, opslen, solve_constraints}; use rhoevm::modules::expr::is_function_sig_check_prop; use rhoevm::modules::format::{hex_byte_string, strip_0x}; use rhoevm::modules::smt::parse_z3_output; use rhoevm::modules::transactions::init_tx; -use rhoevm::modules::types::{ContractCode, Env, Expr, Prop, RuntimeCodeStruct, EXPR_MEMPTY, VM, W256}; +use rhoevm::modules::types::{ + ByteString, ContractCode, Env, EvmError, Expr, Prop, RuntimeCodeStruct, VMResult, EXPR_MEMPTY, VM, W256, +}; + +const DEFAULT_MAX_NUM_ITERATIONS: u32 = 10; +const DEFAULT_IGNORED_REVERT_LISTS: [u8; 1] = [0x11]; +const DEFAULT_REVERT_STATEMENT: &str = "Panic(uint256)"; #[derive(Debug)] struct Args { @@ -24,6 +30,7 @@ struct Args { function_signatures: String, max_num_iterations: Option, verbose_level: Option, + ignored_panic_codes: HashSet, execute_entire_binary: bool, stop_at_the_first_reachable_revert: bool, } @@ -34,8 +41,6 @@ fn print_usage(program: &str, opts: &Options) { process::exit(0); } -const DEFAULT_MAX_NUM_ITERATIONS: u32 = 10; - fn parse_args() -> Args { let args: Vec = env::args().collect(); let program = args[0].clone(); @@ -43,6 +48,7 @@ fn parse_args() -> Args { let mut opts = Options::new(); opts.optopt("i", "max_num_iterations", "Maximum number of iterations for loop", "MAX_NUM_ITER"); opts.optopt("v", "verbose", "Level of verbose", "LEVEL"); + opts.optopt("p", "ignored_panic_codes", "List of ignored panic codes", "IGNORED_PANIC_CODES"); opts.optflag( "e", "execute_entire_binary", @@ -83,7 +89,13 @@ fn parse_args() -> Args { } else { None }; + let verbose_level = matches.opt_str("v"); + let ignored_panic_codes: HashSet = if let Some(s) = matches.opt_str("p") { + s.split('|').map(|s| s.parse::().unwrap()).collect() + } else { + HashSet::from_iter(DEFAULT_IGNORED_REVERT_LISTS.to_vec().iter().cloned()) + }; let execute_entire_binary = matches.opt_present("e"); let stop_at_the_first_reachable_revert = matches.opt_present("s"); @@ -93,6 +105,7 @@ fn parse_args() -> Args { function_signatures, max_num_iterations, verbose_level, + ignored_panic_codes, execute_entire_binary, stop_at_the_first_reachable_revert, } @@ -181,6 +194,8 @@ async fn main() { } debug!("File '{}' read successfully.", args.bin_file_path); + let panic_bytes: ByteString = selector(DEFAULT_REVERT_STATEMENT); + // utility variables let mut normalized_function_names_vec: Vec = vec![]; let mut function_names_vec: Vec = vec![]; @@ -339,7 +354,29 @@ async fn main() { } if found_calldataload && prev_op == "REVERT" { - potential_reverts.push((vm.state.pc, vm.constraints.clone())); + let mut ignore: bool = false; + if vm.result.clone().is_some() { + if let VMResult::VMFailure(e) = vm.result.clone().unwrap() { + if let EvmError::Revert(r) = e { + if let Expr::ConcreteBuf(b) = *r { + if panic_bytes.len() < b.len() { + for i in 1..panic_bytes.len() { + if panic_bytes[i] != b[i] { + ignore = true; + break; + } + } + if !ignore { + ignore = args.ignored_panic_codes.contains(&b[b.len() - 1]); + } + } + } + } + } + } + if !ignore { + potential_reverts.push((vm.state.pc, vm.constraints.clone())); + } end = true; } diff --git a/src/modules/expr.rs b/src/modules/expr.rs index 74ce122..d7a15e6 100644 --- a/src/modules/expr.rs +++ b/src/modules/expr.rs @@ -820,7 +820,7 @@ pub fn copy_slice(src_offset: &Expr, dst_offset: &Expr, size: &Expr, src: &Expr, let hd = vec![0; dst_offset.0 as usize]; let sl = pad_right( size.0 as usize, - (&src_buf[src_offset.0 as usize..src_offset.0 as usize + size.0 as usize]).to_vec(), + (&src_buf[src_offset.0 as usize..min(src_buf.len(), src_offset.0 as usize + size.0 as usize)]).to_vec(), ); return Expr::ConcreteBuf([hd, sl].concat()); } else {