erc20-vend

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 5d213d61b7421440cd28673604965e0bcd7a709d
parent 7cf174d6a813fb8c86a73c66d2127f6a7e1e4a53
Author: lash <dev@holbrook.no>
Date:   Sun,  7 May 2023 13:24:28 +0100

Add withdraw test, allow withdraw anytime if not locked

Diffstat:
Mpython/erc20_vend/data/Vend.bin | 4++--
Mpython/erc20_vend/data/Vend.metadata.json | 2+-
Mpython/erc20_vend/unittest/__init__.py | 1+
Mpython/erc20_vend/unittest/base.py | 30+++++++++++++++++++++++++++---
Mpython/erc20_vend/vend.py | 27++++++++++++++++++++++++++-
Apython/run_tests.sh | 14++++++++++++++
Mpython/tests/test_base.py | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apython/tests/test_lock.py | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msolidity/Vend.sol | 27++++++++++++++++++++-------
9 files changed, 286 insertions(+), 14 deletions(-)

diff --git a/python/erc20_vend/data/Vend.bin b/python/erc20_vend/data/Vend.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b506040516200439c3803806200439c83398181016040528101906200003791906200038c565b60006060846000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600060156101000a81548160ff021916908360ff16021790555082600260006101000a81548160ff02191690831515021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000179919062000461565b6000604051808303816000865af19150503d8060008114620001b8576040519150601f19603f3d011682016040523d82523d6000602084013e620001bd565b606091505b5080925081935050508162000209576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200020090620004db565b60405180910390fd5b808060200190518101906200021f9190620004fd565b600060146101000a81548160ff021916908360ff160217905550600060159054906101000a900460ff1660ff16600060149054906101000a900460ff1660ff1610156200026b57600080fd5b83600060149054906101000a900460ff166200028891906200055e565b600a620002969190620006f8565b600181905550505050505062000749565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002d982620002ac565b9050919050565b620002eb81620002cc565b8114620002f757600080fd5b50565b6000815190506200030b81620002e0565b92915050565b600060ff82169050919050565b620003298162000311565b81146200033557600080fd5b50565b60008151905062000349816200031e565b92915050565b60008115159050919050565b62000366816200034f565b81146200037257600080fd5b50565b60008151905062000386816200035b565b92915050565b600080600060608486031215620003a857620003a7620002a7565b5b6000620003b886828701620002fa565b9350506020620003cb8682870162000338565b9250506040620003de8682870162000375565b9150509250925092565b600081519050919050565b600081905092915050565b60005b838110156200041e57808201518184015260208101905062000401565b60008484015250505050565b60006200043782620003e8565b620004438185620003f3565b935062000455818560208601620003fe565b80840191505092915050565b60006200046f82846200042a565b915081905092915050565b600082825260208201905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b6000620004c36009836200047a565b9150620004d0826200048b565b602082019050919050565b60006020820190508181036000830152620004f681620004b4565b9050919050565b600060208284031215620005165762000515620002a7565b5b6000620005268482850162000338565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200056b8262000311565b9150620005788362000311565b9250828203905060ff8111156200059457620005936200052f565b5b92915050565b6000600282049050919050565b6000808291508390505b6001851115620005f957808604811115620005d157620005d06200052f565b5b6001851615620005e15780820291505b8081029050620005f1856200059a565b9450620005b1565b94509492505050565b600082620006145760019050620006e7565b81620006245760009050620006e7565b81600181146200063d576002811462000648576200067e565b6001915050620006e7565b60ff8411156200065d576200065c6200052f565b5b8360020a9150848211156200067757620006766200052f565b5b50620006e7565b5060208310610133831016604e8410600b8410161715620006b85782820a905083811115620006b257620006b16200052f565b5b620006e7565b620006c78484846001620005a7565b92509050818404811115620006e157620006e06200052f565b5b81810290505b9392505050565b6000819050919050565b60006200070582620006ee565b9150620007128362000311565b9250620007417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000602565b905092915050565b613c4380620007596000396000f3fe60806040523480156200001157600080fd5b50600436106200006f576000357c010000000000000000000000000000000000000000000000000000000090048063198e2b8a1462000074578063644b7a4314620000aa5780639eca672c14620000e0578063da1919b31462000116575b600080fd5b6200009260048036038101906200008c919062000df0565b6200014c565b604051620000a1919062000ec3565b60405180910390f35b620000c86004803603810190620000c2919062000f1b565b6200025d565b604051620000d7919062000ec3565b60405180910390f35b620000fe6004803603810190620000f8919062000f7e565b620002a8565b6040516200010d919062000fc1565b60405180910390f35b6200013460048036038101906200012e919062000fde565b620005c1565b60405162000143919062000fc1565b60405180910390f35b60008060008087878787600060159054906101000a900460ff166000604051620001769062000d6a565b6200018796959493929190620010f4565b604051809103906000f080158015620001a4573d6000803e3d6000fd5b50925082915060038054905090506003839080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550807fc331dc3e37e2ab4d6e65d42a119ffdfab8481b9be24d26704f9f4b4a331d4dd08360405162000247919062000ec3565b60405180910390a2819350505050949350505050565b60006003828154811062000276576200027562001153565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60008060606000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103620003445760009350505050620005bc565b62000350853362000b1b565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1633826040516024016200043e92919062001182565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051620004ca919062001228565b6000604051808303816000865af19150503d806000811462000509576040519150601f19603f3d011682016040523d82523d6000602084013e6200050e565b606091505b508093508194505050826200055a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005519062001291565b60405180910390fd5b81806020019051810190620005709190620012f0565b925082620005b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005ac9062001372565b60405180910390fd5b8093505050505b919050565b600080600060606000807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff871062000630576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200062790620013e4565b60405180910390fd5b60008703620006485760009550505050505062000b15565b8794506000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146200070d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007049062001456565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040162000764919062000ec3565b602060405180830381865afa15801562000782573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007a891906200148f565b915060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16333089604051602401620007f89392919062001522565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000884919062001228565b6000604051808303816000865af19150503d8060008114620008c3576040519150601f19603f3d011682016040523d82523d6000602084013e620008c8565b606091505b5080945081955050508362000914576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200090b9062001291565b60405180910390fd5b828060200190518101906200092a9190620012f0565b9350836200096f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009669062001372565b60405180910390fd5b600060015403620009835786905062000996565b60015487620009939190620015bd565b90505b86600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825462000a249190620015f5565b925050819055508473ffffffffffffffffffffffffffffffffffffffff1663449a52f833896040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040162000a8492919062001182565b6020604051808303816000875af115801562000aa4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000aca9190620012f0565b62000b0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b039062001680565b60405180910390fd5b86955050505050505b92915050565b6000806060600080600260009054906101000a900460ff161562000d5c578673ffffffffffffffffffffffffffffffffffffffff168660405160240162000b63919062000ec3565b6040516020818303038152906040527f70a08231000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000bef919062001228565b6000604051808303816000865af19150503d806000811462000c2e576040519150601f19603f3d011682016040523d82523d6000602084013e62000c33565b606091505b5080945081955050508362000c7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000c769062001291565b60405180910390fd5b8280602001905181019062000c9591906200148f565b9150600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905080821462000d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000d5290620016f2565b60405180910390fd5b5b600194505050505092915050565b6124f9806200171583390190565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011262000daa5762000da962000d82565b5b8235905067ffffffffffffffff81111562000dca5762000dc962000d87565b5b60208301915083600182028301111562000de95762000de862000d8c565b5b9250929050565b6000806000806040858703121562000e0d5762000e0c62000d78565b5b600085013567ffffffffffffffff81111562000e2e5762000e2d62000d7d565b5b62000e3c8782880162000d91565b9450945050602085013567ffffffffffffffff81111562000e625762000e6162000d7d565b5b62000e708782880162000d91565b925092505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000eab8262000e7e565b9050919050565b62000ebd8162000e9e565b82525050565b600060208201905062000eda600083018462000eb2565b92915050565b6000819050919050565b62000ef58162000ee0565b811462000f0157600080fd5b50565b60008135905062000f158162000eea565b92915050565b60006020828403121562000f345762000f3362000d78565b5b600062000f448482850162000f04565b91505092915050565b62000f588162000e9e565b811462000f6457600080fd5b50565b60008135905062000f788162000f4d565b92915050565b60006020828403121562000f975762000f9662000d78565b5b600062000fa78482850162000f67565b91505092915050565b62000fbb8162000ee0565b82525050565b600060208201905062000fd8600083018462000fb0565b92915050565b6000806040838503121562000ff85762000ff762000d78565b5b6000620010088582860162000f67565b92505060206200101b8582860162000f04565b9150509250929050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600062001064838562001025565b93506200107383858462001036565b6200107e8362001045565b840190509392505050565b600060ff82169050919050565b620010a18162001089565b82525050565b6000819050919050565b6000819050919050565b6000620010dc620010d6620010d084620010a7565b620010b1565b62000ee0565b9050919050565b620010ee81620010bb565b82525050565b600060808201905081810360008301526200111181888a62001056565b905081810360208301526200112881868862001056565b905062001139604083018562001096565b620011486060830184620010e3565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060408201905062001199600083018562000eb2565b620011a8602083018462000fb0565b9392505050565b600081519050919050565b600081905092915050565b60005b83811015620011e5578082015181840152602081019050620011c8565b60008484015250505050565b6000620011fe82620011af565b6200120a8185620011ba565b93506200121c818560208601620011c5565b80840191505092915050565b6000620012368284620011f1565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b60006200127960098362001025565b9150620012868262001241565b602082019050919050565b60006020820190508181036000830152620012ac816200126a565b9050919050565b60008115159050919050565b620012ca81620012b3565b8114620012d657600080fd5b50565b600081519050620012ea81620012bf565b92915050565b60006020828403121562001309576200130862000d78565b5b60006200131984828501620012d9565b91505092915050565b7f4552525f544f4b454e5f5452414e534645520000000000000000000000000000600082015250565b60006200135a60128362001025565b9150620013678262001322565b602082019050919050565b600060208201905081810360008301526200138d816200134b565b9050919050565b7f4552525f56414c55455f544f4f5f484947480000000000000000000000000000600082015250565b6000620013cc60128362001025565b9150620013d98262001394565b602082019050919050565b60006020820190508181036000830152620013ff81620013bd565b9050919050565b7f4552525f55534544000000000000000000000000000000000000000000000000600082015250565b60006200143e60088362001025565b91506200144b8262001406565b602082019050919050565b6000602082019050818103600083015262001471816200142f565b9050919050565b600081519050620014898162000eea565b92915050565b600060208284031215620014a857620014a762000d78565b5b6000620014b88482850162001478565b91505092915050565b6000620014e2620014dc620014d68462000e7e565b620010b1565b62000e7e565b9050919050565b6000620014f682620014c1565b9050919050565b60006200150a82620014e9565b9050919050565b6200151c81620014fd565b82525050565b600060608201905062001539600083018662000eb2565b62001548602083018562001511565b62001557604083018462000fb0565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620015ca8262000ee0565b9150620015d78362000ee0565b925082620015ea57620015e96200155f565b5b828204905092915050565b6000620016028262000ee0565b91506200160f8362000ee0565b92508282019050808211156200162a57620016296200158e565b5b92915050565b7f4552525f4d494e54000000000000000000000000000000000000000000000000600082015250565b60006200166860088362001025565b9150620016758262001630565b602082019050919050565b600060208201905081810360008301526200169b8162001659565b9050919050565b7f4552525f4c4f434b454400000000000000000000000000000000000000000000600082015250565b6000620016da600a8362001025565b9150620016e782620016a2565b602082019050919050565b600060208201905081810360008301526200170d81620016cb565b905091905056fe60806040523480156200001157600080fd5b50604051620024f9380380620024f98339818101604052810190620000379190620002d3565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360029081620000889190620005ca565b5082600390816200009a9190620005ca565b5081600460006101000a81548160ff021916908360ff1602179055508060098190555050505050620006b1565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200013082620000e5565b810181811067ffffffffffffffff82111715620001525762000151620000f6565b5b80604052505050565b600062000167620000c7565b905062000175828262000125565b919050565b600067ffffffffffffffff821115620001985762000197620000f6565b5b620001a382620000e5565b9050602081019050919050565b60005b83811015620001d0578082015181840152602081019050620001b3565b60008484015250505050565b6000620001f3620001ed846200017a565b6200015b565b905082815260208101848484011115620002125762000211620000e0565b5b6200021f848285620001b0565b509392505050565b600082601f8301126200023f576200023e620000db565b5b815162000251848260208601620001dc565b91505092915050565b600060ff82169050919050565b62000272816200025a565b81146200027e57600080fd5b50565b600081519050620002928162000267565b92915050565b6000819050919050565b620002ad8162000298565b8114620002b957600080fd5b50565b600081519050620002cd81620002a2565b92915050565b60008060008060808587031215620002f057620002ef620000d1565b5b600085015167ffffffffffffffff811115620003115762000310620000d6565b5b6200031f8782880162000227565b945050602085015167ffffffffffffffff811115620003435762000342620000d6565b5b620003518782880162000227565b9350506040620003648782880162000281565b92505060606200037787828801620002bc565b91505092959194509250565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620003d657607f821691505b602082108103620003ec57620003eb6200038e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620004597fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000417565b62000465868362000417565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620004a8620004a26200049c8462000298565b6200047d565b62000298565b9050919050565b6000819050919050565b620004c48362000487565b620004dc620004d382620004af565b84845462000427565b825550505050565b600090565b620004f3620004e4565b62000500818484620004b9565b505050565b5b8181101562000528576200051c600082620004e9565b60018101905062000506565b5050565b601f82111562000577576200054181620003f2565b6200054c8462000407565b810160208510156200055c578190505b620005746200056b8562000407565b83018262000505565b50505b505050565b60008160020a8304905092915050565b60006200059f600019846008026200057c565b1980831691505092915050565b6000620005ba83836200058c565b9150826002028217905092915050565b620005d58262000383565b67ffffffffffffffff811115620005f157620005f0620000f6565b5b620005fd8254620003bd565b6200060a8282856200052c565b600060209050601f8311600181146200064257600084156200062d578287015190505b620006398582620005ac565b865550620006a9565b601f1984166200065286620003f2565b60005b828110156200067c5784890151825560018201915060208501945060208101905062000655565b868310156200069c578489015162000698601f8916826200058c565b8355505b6001600288020188555050505b505050505050565b611e3880620006c16000396000f3fe608060405234801561001057600080fd5b5060043610610175576000357c0100000000000000000000000000000000000000000000000000000000900480635f408c04116100e0578063a9059cbb11610099578063a9059cbb14610422578063b1cb0db314610452578063d89135cd14610470578063da2824a81461048e578063dd62ed3e146104be578063f2fde38b146104ee57610175565b80635f408c041461035e57806370a082311461037c5780638da5cb5b146103ac57806394d008ef146103ca57806395d89b41146103e6578063a2309ff81461040457610175565b8063313ce56711610132578063313ce5671461027657806342966c6814610294578063449a52f8146102c457806344d17187146102f457806344df8e70146103105780635ae06f7e1461032e57610175565b806301ffc9a71461017a57806306fdde03146101aa578063095ea7b3146101c857806318160ddd146101f857806323b872dd146102165780632b29ba2314610246575b600080fd5b610194600480360381019061018f919061178d565b61051e565b6040516101a191906117d5565b60405180910390f35b6101b2610768565b6040516101bf9190611880565b60405180910390f35b6101e260048036038101906101dd9190611936565b6107f6565b6040516101ef91906117d5565b60405180910390f35b610200610991565b60405161020d9190611985565b60405180910390f35b610230600480360381019061022b91906119a0565b6109a8565b60405161023d91906117d5565b60405180910390f35b610260600480360381019061025b91906119f3565b610cd0565b60405161026d91906117d5565b60405180910390f35b61027e610d7c565b60405161028b9190611a3c565b60405180910390f35b6102ae60048036038101906102a99190611a57565b610d8f565b6040516102bb91906117d5565b60405180910390f35b6102de60048036038101906102d99190611936565b610f51565b6040516102eb91906117d5565b60405180910390f35b61030e60048036038101906103099190611ae9565b6110dd565b005b61031861115b565b60405161032591906117d5565b60405180910390f35b610348600480360381019061034391906119f3565b6111aa565b60405161035591906117d5565b60405180910390f35b61036661129c565b6040516103739190611a3c565b60405180910390f35b610396600480360381019061039191906119f3565b61133a565b6040516103a39190611985565b60405180910390f35b6103b4611352565b6040516103c19190611b6c565b60405180910390f35b6103e460048036038101906103df9190611ae9565b611376565b005b6103ee611387565b6040516103fb9190611880565b60405180910390f35b61040c611415565b6040516104199190611985565b60405180910390f35b61043c60048036038101906104379190611936565b61141b565b60405161044991906117d5565b60405180910390f35b61045a61159a565b6040516104679190611985565b60405180910390f35b6104786115a0565b6040516104859190611985565b60405180910390f35b6104a860048036038101906104a391906119f3565b6115a6565b6040516104b591906117d5565b60405180910390f35b6104d860048036038101906104d39190611b87565b611662565b6040516104e59190611985565b60405180910390f35b610508600480360381019061050391906119f3565b611687565b60405161051591906117d5565b60405180910390f35b600063b61bc9417c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036105725760019050610763565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036105c45760019050610763565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106165760019050610763565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106685760019050610763565b63abe1f1f57c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106ba5760019050610763565b63b1110c1b7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361070c5760019050610763565b63841a0e947c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361075e5760019050610763565b600090505b919050565b6002805461077590611bf6565b80601f01602080910402602001604051908101604052809291908181526020018280546107a190611bf6565b80156107ee5780601f106107c3576101008083540402835291602001916107ee565b820191906000526020600020905b8154815290600101906020018083116107d157829003601f168201915b505050505081565b60008061080161129c565b60ff161461080e57600080fd5b60008211156108a1576000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146108a057600080fd5b5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161097f9190611985565b60405180910390a36001905092915050565b60006008546007546109a39190611c56565b905090565b6000806109b361129c565b60ff16146109c057600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610a4957600080fd5b81600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610a9557600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d9190611c56565b600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610bec9190611c56565b9250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c429190611c8a565b925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f93985604051610cbd9190611985565b60405180910390a4600190509392505050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680610d75575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050919050565b600460009054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1790611d0a565b60405180910390fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610ea2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9990611d76565b60405180910390fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610ef19190611c56565b925050819055508160086000828254610f0a9190611c8a565b925050819055507fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb82604051610f409190611985565b60405180910390a160019050919050565b6000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680610ff6575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610fff57600080fd5b81600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461104e9190611c8a565b9250508190555081600760008282546110679190611c8a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8846040516110cb9190611985565b60405180910390a36001905092915050565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461114b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114290611de2565b60405180910390fd5b61115483610d8f565b5050505050565b60006111a5600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d8f565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061123257508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61123b57600080fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600080600954036112b05760009050611337565b600a60009054906101000a900460ff16156112ce5760019050611337565b6009544210611332576001600a60006101000a81548160ff0219169083151502179055507ff80dbaea4785589e52984ca36a31de106adc77759539a5c7d92883bf49692fe9426040516113219190611985565b60405180910390a160029050611337565b600090505b90565b60056020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6113808484610f51565b5050505050565b6003805461139490611bf6565b80601f01602080910402602001604051908101604052809291908181526020018280546113c090611bf6565b801561140d5780601f106113e25761010080835404028352916020019161140d565b820191906000526020600020905b8154815290600101906020018083116113f057829003601f168201915b505050505081565b60075481565b60008061142661129c565b60ff161461143357600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561147f57600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546114ce9190611c56565b9250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546115249190611c8a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516115889190611985565b60405180910390a36001905092915050565b60095481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461160157600080fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6006602052816000526040600020602052806000526040600020600091509150505481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116e257600080fd5b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61176a81611735565b811461177557600080fd5b50565b60008135905061178781611761565b92915050565b6000602082840312156117a3576117a261172b565b5b60006117b184828501611778565b91505092915050565b60008115159050919050565b6117cf816117ba565b82525050565b60006020820190506117ea60008301846117c6565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561182a57808201518184015260208101905061180f565b60008484015250505050565b6000601f19601f8301169050919050565b6000611852826117f0565b61185c81856117fb565b935061186c81856020860161180c565b61187581611836565b840191505092915050565b6000602082019050818103600083015261189a8184611847565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006118cd826118a2565b9050919050565b6118dd816118c2565b81146118e857600080fd5b50565b6000813590506118fa816118d4565b92915050565b6000819050919050565b61191381611900565b811461191e57600080fd5b50565b6000813590506119308161190a565b92915050565b6000806040838503121561194d5761194c61172b565b5b600061195b858286016118eb565b925050602061196c85828601611921565b9150509250929050565b61197f81611900565b82525050565b600060208201905061199a6000830184611976565b92915050565b6000806000606084860312156119b9576119b861172b565b5b60006119c7868287016118eb565b93505060206119d8868287016118eb565b92505060406119e986828701611921565b9150509250925092565b600060208284031215611a0957611a0861172b565b5b6000611a17848285016118eb565b91505092915050565b600060ff82169050919050565b611a3681611a20565b82525050565b6000602082019050611a516000830184611a2d565b92915050565b600060208284031215611a6d57611a6c61172b565b5b6000611a7b84828501611921565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611aa957611aa8611a84565b5b8235905067ffffffffffffffff811115611ac657611ac5611a89565b5b602083019150836001820283011115611ae257611ae1611a8e565b5b9250929050565b60008060008060608587031215611b0357611b0261172b565b5b6000611b11878288016118eb565b9450506020611b2287828801611921565b935050604085013567ffffffffffffffff811115611b4357611b42611730565b5b611b4f87828801611a93565b925092505092959194509250565b611b66816118c2565b82525050565b6000602082019050611b816000830184611b5d565b92915050565b60008060408385031215611b9e57611b9d61172b565b5b6000611bac858286016118eb565b9250506020611bbd858286016118eb565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611c0e57607f821691505b602082108103611c2157611c20611bc7565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611c6182611900565b9150611c6c83611900565b9250828203905081811115611c8457611c83611c27565b5b92915050565b6000611c9582611900565b9150611ca083611900565b9250828201905080821115611cb857611cb7611c27565b5b92915050565b7f4552525f41434345535300000000000000000000000000000000000000000000600082015250565b6000611cf4600a836117fb565b9150611cff82611cbe565b602082019050919050565b60006020820190508181036000830152611d2381611ce7565b9050919050565b7f4552525f46554e44530000000000000000000000000000000000000000000000600082015250565b6000611d606009836117fb565b9150611d6b82611d2a565b602082019050919050565b60006020820190508181036000830152611d8f81611d53565b9050919050565b7f4552525f4e4f545f53454c460000000000000000000000000000000000000000600082015250565b6000611dcc600c836117fb565b9150611dd782611d96565b602082019050919050565b60006020820190508181036000830152611dfb81611dbf565b905091905056fea26469706673582212207c618c5e739ffaab5926ea597eb54f0122f3f64b626f5a26fb110c7779f25e7564736f6c63430008130033a2646970667358221220a9ace913705e7a64a778d74f4bb56fa69cf902677ecd6739b576b3dd901b082364736f6c63430008130033 -\ No newline at end of file +60806040523480156200001157600080fd5b50604051620048c1380380620048c183398181016040528101906200003791906200039f565b60006060846000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600060156101000a81548160ff021916908360ff16021790555082600260006101000a81548160ff02191690831515021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000179919062000474565b6000604051808303816000865af19150503d8060008114620001b8576040519150601f19603f3d011682016040523d82523d6000602084013e620001bd565b606091505b5080925081935050508162000209576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200020090620004ee565b60405180910390fd5b808060200190518101906200021f919062000510565b600060146101000a81548160ff021916908360ff160217905550600060159054906101000a900460ff1660ff16600060149054906101000a900460ff1660ff1610156200026b57600080fd5b83600060149054906101000a900460ff1662000288919062000571565b600a6200029691906200070b565b600181905550600060015403620002af57600180819055505b50505050506200075c565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002ec82620002bf565b9050919050565b620002fe81620002df565b81146200030a57600080fd5b50565b6000815190506200031e81620002f3565b92915050565b600060ff82169050919050565b6200033c8162000324565b81146200034857600080fd5b50565b6000815190506200035c8162000331565b92915050565b60008115159050919050565b620003798162000362565b81146200038557600080fd5b50565b60008151905062000399816200036e565b92915050565b600080600060608486031215620003bb57620003ba620002ba565b5b6000620003cb868287016200030d565b9350506020620003de868287016200034b565b9250506040620003f18682870162000388565b9150509250925092565b600081519050919050565b600081905092915050565b60005b838110156200043157808201518184015260208101905062000414565b60008484015250505050565b60006200044a82620003fb565b62000456818562000406565b93506200046881856020860162000411565b80840191505092915050565b60006200048282846200043d565b915081905092915050565b600082825260208201905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b6000620004d66009836200048d565b9150620004e3826200049e565b602082019050919050565b600060208201905081810360008301526200050981620004c7565b9050919050565b600060208284031215620005295762000528620002ba565b5b600062000539848285016200034b565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200057e8262000324565b91506200058b8362000324565b9250828203905060ff811115620005a757620005a662000542565b5b92915050565b6000600282049050919050565b6000808291508390505b60018511156200060c57808604811115620005e457620005e362000542565b5b6001851615620005f45780820291505b80810290506200060485620005ad565b9450620005c4565b94509492505050565b600082620006275760019050620006fa565b81620006375760009050620006fa565b81600181146200065057600281146200065b5762000691565b6001915050620006fa565b60ff84111562000670576200066f62000542565b5b8360020a9150848211156200068a576200068962000542565b5b50620006fa565b5060208310610133831016604e8410600b8410161715620006cb5782820a905083811115620006c557620006c462000542565b5b620006fa565b620006da8484846001620005ba565b92509050818404811115620006f457620006f362000542565b5b81810290505b9392505050565b6000819050919050565b6000620007188262000701565b9150620007258362000324565b9250620007547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000615565b905092915050565b614155806200076c6000396000f3fe60806040523480156200001157600080fd5b50600436106200006f576000357c010000000000000000000000000000000000000000000000000000000090048063198e2b8a1462000074578063644b7a4314620000aa5780639eca672c14620000e0578063da1919b31462000116575b600080fd5b6200009260048036038101906200008c9190620011d3565b6200014c565b604051620000a19190620012a6565b60405180910390f35b620000c86004803603810190620000c29190620012fe565b6200025d565b604051620000d79190620012a6565b60405180910390f35b620000fe6004803603810190620000f8919062001361565b620002a8565b6040516200010d9190620013a4565b60405180910390f35b6200013460048036038101906200012e9190620013c1565b62000a09565b604051620001439190620013a4565b60405180910390f35b60008060008087878787600060159054906101000a900460ff16600060405162000176906200114d565b6200018796959493929190620014d7565b604051809103906000f080158015620001a4573d6000803e3d6000fd5b50925082915060038054905090506003839080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550807fc331dc3e37e2ab4d6e65d42a119ffdfab8481b9be24d26704f9f4b4a331d4dd083604051620002479190620012a6565b60405180910390a2819350505050949350505050565b60006003828154811062000276576200027562001536565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000806060600080600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082036200034657600094505050505062000a04565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541062000427576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200041e90620015b5565b60405180910390fd5b62000433863362000ec3565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101562000839578573ffffffffffffffffffffffffffffffffffffffff163330836040516024016200052d9392919062001638565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051620005b99190620016ee565b6000604051808303816000865af19150503d8060008114620005f8576040519150601f19603f3d011682016040523d82523d6000602084013e620005fd565b606091505b5080945081955050508362000649576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006409062001757565b60405180910390fd5b828060200190518101906200065f9190620017b6565b935083620006a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200069b9062001838565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f44df8e70000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516200074d9190620016ee565b6000604051808303816000865af19150503d80600081146200078c576040519150601f19603f3d011682016040523d82523d6000602084013e62000791565b606091505b50809450819550505083620007dd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007d49062001757565b60405180910390fd5b82806020019051810190620007f39190620017b6565b93508362000838576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200082f90620018aa565b60405180910390fd5b5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16338360405160240162000885929190620018cc565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051620009119190620016ee565b6000604051808303816000865af19150503d806000811462000950576040519150601f19603f3d011682016040523d82523d6000602084013e62000955565b606091505b50809450819550505083620009a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009989062001757565b60405180910390fd5b82806020019051810190620009b79190620017b6565b935083620009fc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009f39062001838565b60405180910390fd5b819450505050505b919050565b6000806000606060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861062000a77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000a6e9062001949565b60405180910390fd5b6000860362000a8e57600094505050505062000ebd565b8693506000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541462000b53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b4a90620019bb565b60405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1633308860405160240162000ba19392919062001638565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000c2d9190620016ee565b6000604051808303816000865af19150503d806000811462000c6c576040519150601f19603f3d011682016040523d82523d6000602084013e62000c71565b606091505b5080935081945050508262000cbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000cb49062001757565b60405180910390fd5b8180602001905181019062000cd39190620017b6565b92508262000d18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000d0f9062001838565b60405180910390fd5b60006001540362000d2c5785905062000d3f565b6001548662000d3c919062001a3b565b90505b85600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825462000dcd919062001a73565b925050819055508373ffffffffffffffffffffffffffffffffffffffff1663449a52f833836040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040162000e2d929190620018cc565b6020604051808303816000875af115801562000e4d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e739190620017b6565b62000eb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000eac9062001afe565b60405180910390fd5b859450505050505b92915050565b6000806060600080600260009054906101000a900460ff16156200111f578673ffffffffffffffffffffffffffffffffffffffff168660405160240162000f0b9190620012a6565b6040516020818303038152906040527f70a08231000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000f979190620016ee565b6000604051808303816000865af19150503d806000811462000fd6576040519150601f19603f3d011682016040523d82523d6000602084013e62000fdb565b606091505b5080945081955050508362001027576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200101e9062001757565b60405180910390fd5b828060200190518101906200103d919062001b37565b9150600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508060015483620010cf919062001b69565b1462001112576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620011099062001c04565b60405180910390fd5b8194505050505062001147565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9450505050505b92915050565b6124f98062001c2783390190565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126200118d576200118c62001165565b5b8235905067ffffffffffffffff811115620011ad57620011ac6200116a565b5b602083019150836001820283011115620011cc57620011cb6200116f565b5b9250929050565b60008060008060408587031215620011f057620011ef6200115b565b5b600085013567ffffffffffffffff81111562001211576200121062001160565b5b6200121f8782880162001174565b9450945050602085013567ffffffffffffffff81111562001245576200124462001160565b5b620012538782880162001174565b925092505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200128e8262001261565b9050919050565b620012a08162001281565b82525050565b6000602082019050620012bd600083018462001295565b92915050565b6000819050919050565b620012d881620012c3565b8114620012e457600080fd5b50565b600081359050620012f881620012cd565b92915050565b6000602082840312156200131757620013166200115b565b5b60006200132784828501620012e7565b91505092915050565b6200133b8162001281565b81146200134757600080fd5b50565b6000813590506200135b8162001330565b92915050565b6000602082840312156200137a57620013796200115b565b5b60006200138a848285016200134a565b91505092915050565b6200139e81620012c3565b82525050565b6000602082019050620013bb600083018462001393565b92915050565b60008060408385031215620013db57620013da6200115b565b5b6000620013eb858286016200134a565b9250506020620013fe85828601620012e7565b9150509250929050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600062001447838562001408565b93506200145683858462001419565b620014618362001428565b840190509392505050565b600060ff82169050919050565b62001484816200146c565b82525050565b6000819050919050565b6000819050919050565b6000620014bf620014b9620014b3846200148a565b62001494565b620012c3565b9050919050565b620014d1816200149e565b82525050565b60006080820190508181036000830152620014f481888a62001439565b905081810360208301526200150b81868862001439565b90506200151c604083018562001479565b6200152b6060830184620014c6565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552525f414c52454144595f57495448445241574e0000000000000000000000600082015250565b60006200159d60158362001408565b9150620015aa8262001565565b602082019050919050565b60006020820190508181036000830152620015d0816200158e565b9050919050565b6000620015f8620015f2620015ec8462001261565b62001494565b62001261565b9050919050565b60006200160c82620015d7565b9050919050565b60006200162082620015ff565b9050919050565b620016328162001613565b82525050565b60006060820190506200164f600083018662001295565b6200165e602083018562001627565b6200166d604083018462001393565b949350505050565b600081519050919050565b600081905092915050565b60005b83811015620016ab5780820151818401526020810190506200168e565b60008484015250505050565b6000620016c48262001675565b620016d0818562001680565b9350620016e28185602086016200168b565b80840191505092915050565b6000620016fc8284620016b7565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b60006200173f60098362001408565b91506200174c8262001707565b602082019050919050565b60006020820190508181036000830152620017728162001730565b9050919050565b60008115159050919050565b620017908162001779565b81146200179c57600080fd5b50565b600081519050620017b08162001785565b92915050565b600060208284031215620017cf57620017ce6200115b565b5b6000620017df848285016200179f565b91505092915050565b7f4552525f544f4b454e5f5452414e534645520000000000000000000000000000600082015250565b60006200182060128362001408565b91506200182d82620017e8565b602082019050919050565b60006020820190508181036000830152620018538162001811565b9050919050565b7f4552525f544f4b454e5f4255524e000000000000000000000000000000000000600082015250565b600062001892600e8362001408565b91506200189f826200185a565b602082019050919050565b60006020820190508181036000830152620018c58162001883565b9050919050565b6000604082019050620018e3600083018562001295565b620018f2602083018462001393565b9392505050565b7f4552525f56414c55455f544f4f5f484947480000000000000000000000000000600082015250565b60006200193160128362001408565b91506200193e82620018f9565b602082019050919050565b60006020820190508181036000830152620019648162001922565b9050919050565b7f4552525f55534544000000000000000000000000000000000000000000000000600082015250565b6000620019a360088362001408565b9150620019b0826200196b565b602082019050919050565b60006020820190508181036000830152620019d68162001994565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062001a4882620012c3565b915062001a5583620012c3565b92508262001a685762001a67620019dd565b5b828204905092915050565b600062001a8082620012c3565b915062001a8d83620012c3565b925082820190508082111562001aa85762001aa762001a0c565b5b92915050565b7f4552525f4d494e54000000000000000000000000000000000000000000000000600082015250565b600062001ae660088362001408565b915062001af38262001aae565b602082019050919050565b6000602082019050818103600083015262001b198162001ad7565b9050919050565b60008151905062001b3181620012cd565b92915050565b60006020828403121562001b505762001b4f6200115b565b5b600062001b608482850162001b20565b91505092915050565b600062001b7682620012c3565b915062001b8383620012c3565b925082820262001b9381620012c3565b9150828204841483151762001bad5762001bac62001a0c565b5b5092915050565b7f4552525f4c4f434b454400000000000000000000000000000000000000000000600082015250565b600062001bec600a8362001408565b915062001bf98262001bb4565b602082019050919050565b6000602082019050818103600083015262001c1f8162001bdd565b905091905056fe60806040523480156200001157600080fd5b50604051620024f9380380620024f98339818101604052810190620000379190620002d3565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360029081620000889190620005ca565b5082600390816200009a9190620005ca565b5081600460006101000a81548160ff021916908360ff1602179055508060098190555050505050620006b1565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200013082620000e5565b810181811067ffffffffffffffff82111715620001525762000151620000f6565b5b80604052505050565b600062000167620000c7565b905062000175828262000125565b919050565b600067ffffffffffffffff821115620001985762000197620000f6565b5b620001a382620000e5565b9050602081019050919050565b60005b83811015620001d0578082015181840152602081019050620001b3565b60008484015250505050565b6000620001f3620001ed846200017a565b6200015b565b905082815260208101848484011115620002125762000211620000e0565b5b6200021f848285620001b0565b509392505050565b600082601f8301126200023f576200023e620000db565b5b815162000251848260208601620001dc565b91505092915050565b600060ff82169050919050565b62000272816200025a565b81146200027e57600080fd5b50565b600081519050620002928162000267565b92915050565b6000819050919050565b620002ad8162000298565b8114620002b957600080fd5b50565b600081519050620002cd81620002a2565b92915050565b60008060008060808587031215620002f057620002ef620000d1565b5b600085015167ffffffffffffffff811115620003115762000310620000d6565b5b6200031f8782880162000227565b945050602085015167ffffffffffffffff811115620003435762000342620000d6565b5b620003518782880162000227565b9350506040620003648782880162000281565b92505060606200037787828801620002bc565b91505092959194509250565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620003d657607f821691505b602082108103620003ec57620003eb6200038e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620004597fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000417565b62000465868362000417565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620004a8620004a26200049c8462000298565b6200047d565b62000298565b9050919050565b6000819050919050565b620004c48362000487565b620004dc620004d382620004af565b84845462000427565b825550505050565b600090565b620004f3620004e4565b62000500818484620004b9565b505050565b5b8181101562000528576200051c600082620004e9565b60018101905062000506565b5050565b601f82111562000577576200054181620003f2565b6200054c8462000407565b810160208510156200055c578190505b620005746200056b8562000407565b83018262000505565b50505b505050565b60008160020a8304905092915050565b60006200059f600019846008026200057c565b1980831691505092915050565b6000620005ba83836200058c565b9150826002028217905092915050565b620005d58262000383565b67ffffffffffffffff811115620005f157620005f0620000f6565b5b620005fd8254620003bd565b6200060a8282856200052c565b600060209050601f8311600181146200064257600084156200062d578287015190505b620006398582620005ac565b865550620006a9565b601f1984166200065286620003f2565b60005b828110156200067c5784890151825560018201915060208501945060208101905062000655565b868310156200069c578489015162000698601f8916826200058c565b8355505b6001600288020188555050505b505050505050565b611e3880620006c16000396000f3fe608060405234801561001057600080fd5b5060043610610175576000357c0100000000000000000000000000000000000000000000000000000000900480635f408c04116100e0578063a9059cbb11610099578063a9059cbb14610422578063b1cb0db314610452578063d89135cd14610470578063da2824a81461048e578063dd62ed3e146104be578063f2fde38b146104ee57610175565b80635f408c041461035e57806370a082311461037c5780638da5cb5b146103ac57806394d008ef146103ca57806395d89b41146103e6578063a2309ff81461040457610175565b8063313ce56711610132578063313ce5671461027657806342966c6814610294578063449a52f8146102c457806344d17187146102f457806344df8e70146103105780635ae06f7e1461032e57610175565b806301ffc9a71461017a57806306fdde03146101aa578063095ea7b3146101c857806318160ddd146101f857806323b872dd146102165780632b29ba2314610246575b600080fd5b610194600480360381019061018f919061178d565b61051e565b6040516101a191906117d5565b60405180910390f35b6101b2610768565b6040516101bf9190611880565b60405180910390f35b6101e260048036038101906101dd9190611936565b6107f6565b6040516101ef91906117d5565b60405180910390f35b610200610991565b60405161020d9190611985565b60405180910390f35b610230600480360381019061022b91906119a0565b6109a8565b60405161023d91906117d5565b60405180910390f35b610260600480360381019061025b91906119f3565b610cd0565b60405161026d91906117d5565b60405180910390f35b61027e610d7c565b60405161028b9190611a3c565b60405180910390f35b6102ae60048036038101906102a99190611a57565b610d8f565b6040516102bb91906117d5565b60405180910390f35b6102de60048036038101906102d99190611936565b610f51565b6040516102eb91906117d5565b60405180910390f35b61030e60048036038101906103099190611ae9565b6110dd565b005b61031861115b565b60405161032591906117d5565b60405180910390f35b610348600480360381019061034391906119f3565b6111aa565b60405161035591906117d5565b60405180910390f35b61036661129c565b6040516103739190611a3c565b60405180910390f35b610396600480360381019061039191906119f3565b61133a565b6040516103a39190611985565b60405180910390f35b6103b4611352565b6040516103c19190611b6c565b60405180910390f35b6103e460048036038101906103df9190611ae9565b611376565b005b6103ee611387565b6040516103fb9190611880565b60405180910390f35b61040c611415565b6040516104199190611985565b60405180910390f35b61043c60048036038101906104379190611936565b61141b565b60405161044991906117d5565b60405180910390f35b61045a61159a565b6040516104679190611985565b60405180910390f35b6104786115a0565b6040516104859190611985565b60405180910390f35b6104a860048036038101906104a391906119f3565b6115a6565b6040516104b591906117d5565b60405180910390f35b6104d860048036038101906104d39190611b87565b611662565b6040516104e59190611985565b60405180910390f35b610508600480360381019061050391906119f3565b611687565b60405161051591906117d5565b60405180910390f35b600063b61bc9417c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036105725760019050610763565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036105c45760019050610763565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106165760019050610763565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106685760019050610763565b63abe1f1f57c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106ba5760019050610763565b63b1110c1b7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361070c5760019050610763565b63841a0e947c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361075e5760019050610763565b600090505b919050565b6002805461077590611bf6565b80601f01602080910402602001604051908101604052809291908181526020018280546107a190611bf6565b80156107ee5780601f106107c3576101008083540402835291602001916107ee565b820191906000526020600020905b8154815290600101906020018083116107d157829003601f168201915b505050505081565b60008061080161129c565b60ff161461080e57600080fd5b60008211156108a1576000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146108a057600080fd5b5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161097f9190611985565b60405180910390a36001905092915050565b60006008546007546109a39190611c56565b905090565b6000806109b361129c565b60ff16146109c057600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610a4957600080fd5b81600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610a9557600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d9190611c56565b600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610bec9190611c56565b9250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c429190611c8a565b925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f93985604051610cbd9190611985565b60405180910390a4600190509392505050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680610d75575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050919050565b600460009054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1790611d0a565b60405180910390fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610ea2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9990611d76565b60405180910390fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610ef19190611c56565b925050819055508160086000828254610f0a9190611c8a565b925050819055507fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb82604051610f409190611985565b60405180910390a160019050919050565b6000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680610ff6575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610fff57600080fd5b81600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461104e9190611c8a565b9250508190555081600760008282546110679190611c8a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8846040516110cb9190611985565b60405180910390a36001905092915050565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461114b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114290611de2565b60405180910390fd5b61115483610d8f565b5050505050565b60006111a5600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d8f565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061123257508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61123b57600080fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600080600954036112b05760009050611337565b600a60009054906101000a900460ff16156112ce5760019050611337565b6009544210611332576001600a60006101000a81548160ff0219169083151502179055507ff80dbaea4785589e52984ca36a31de106adc77759539a5c7d92883bf49692fe9426040516113219190611985565b60405180910390a160029050611337565b600090505b90565b60056020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6113808484610f51565b5050505050565b6003805461139490611bf6565b80601f01602080910402602001604051908101604052809291908181526020018280546113c090611bf6565b801561140d5780601f106113e25761010080835404028352916020019161140d565b820191906000526020600020905b8154815290600101906020018083116113f057829003601f168201915b505050505081565b60075481565b60008061142661129c565b60ff161461143357600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561147f57600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546114ce9190611c56565b9250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546115249190611c8a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516115889190611985565b60405180910390a36001905092915050565b60095481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461160157600080fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6006602052816000526040600020602052806000526040600020600091509150505481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116e257600080fd5b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61176a81611735565b811461177557600080fd5b50565b60008135905061178781611761565b92915050565b6000602082840312156117a3576117a261172b565b5b60006117b184828501611778565b91505092915050565b60008115159050919050565b6117cf816117ba565b82525050565b60006020820190506117ea60008301846117c6565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561182a57808201518184015260208101905061180f565b60008484015250505050565b6000601f19601f8301169050919050565b6000611852826117f0565b61185c81856117fb565b935061186c81856020860161180c565b61187581611836565b840191505092915050565b6000602082019050818103600083015261189a8184611847565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006118cd826118a2565b9050919050565b6118dd816118c2565b81146118e857600080fd5b50565b6000813590506118fa816118d4565b92915050565b6000819050919050565b61191381611900565b811461191e57600080fd5b50565b6000813590506119308161190a565b92915050565b6000806040838503121561194d5761194c61172b565b5b600061195b858286016118eb565b925050602061196c85828601611921565b9150509250929050565b61197f81611900565b82525050565b600060208201905061199a6000830184611976565b92915050565b6000806000606084860312156119b9576119b861172b565b5b60006119c7868287016118eb565b93505060206119d8868287016118eb565b92505060406119e986828701611921565b9150509250925092565b600060208284031215611a0957611a0861172b565b5b6000611a17848285016118eb565b91505092915050565b600060ff82169050919050565b611a3681611a20565b82525050565b6000602082019050611a516000830184611a2d565b92915050565b600060208284031215611a6d57611a6c61172b565b5b6000611a7b84828501611921565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611aa957611aa8611a84565b5b8235905067ffffffffffffffff811115611ac657611ac5611a89565b5b602083019150836001820283011115611ae257611ae1611a8e565b5b9250929050565b60008060008060608587031215611b0357611b0261172b565b5b6000611b11878288016118eb565b9450506020611b2287828801611921565b935050604085013567ffffffffffffffff811115611b4357611b42611730565b5b611b4f87828801611a93565b925092505092959194509250565b611b66816118c2565b82525050565b6000602082019050611b816000830184611b5d565b92915050565b60008060408385031215611b9e57611b9d61172b565b5b6000611bac858286016118eb565b9250506020611bbd858286016118eb565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611c0e57607f821691505b602082108103611c2157611c20611bc7565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611c6182611900565b9150611c6c83611900565b9250828203905081811115611c8457611c83611c27565b5b92915050565b6000611c9582611900565b9150611ca083611900565b9250828201905080821115611cb857611cb7611c27565b5b92915050565b7f4552525f41434345535300000000000000000000000000000000000000000000600082015250565b6000611cf4600a836117fb565b9150611cff82611cbe565b602082019050919050565b60006020820190508181036000830152611d2381611ce7565b9050919050565b7f4552525f46554e44530000000000000000000000000000000000000000000000600082015250565b6000611d606009836117fb565b9150611d6b82611d2a565b602082019050919050565b60006020820190508181036000830152611d8f81611d53565b9050919050565b7f4552525f4e4f545f53454c460000000000000000000000000000000000000000600082015250565b6000611dcc600c836117fb565b9150611dd782611d96565b602082019050919050565b60006020820190508181036000830152611dfb81611dbf565b905091905056fea26469706673582212207c618c5e739ffaab5926ea597eb54f0122f3f64b626f5a26fb110c7779f25e7564736f6c63430008130033a2646970667358221220d0c2d4729877481a53eeca1a38e85eb7d3a55f58aa3c2f02a62c3739325a236a64736f6c63430008130033 +\ No newline at end of file diff --git a/python/erc20_vend/data/Vend.metadata.json b/python/erc20_vend/data/Vend.metadata.json @@ -1 +1 @@ -{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_controlToken","type":"address"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"bool","name":"_lock","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_idx","type":"uint256"},{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"TokenCreated","type":"event"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"create","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"getTokenByIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"mintFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"withdrawFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"Vend.sol":"ERC20Vend"},"evmVersion":"byzantium","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"GiftableToken.sol":{"keccak256":"0xaa3263856dd73d7bb1ec06b4ca38dd86ddd0771e8cb2ca47b7c1e3c69be9c14a","license":"AGPL-3.0-or-later","urls":["bzz-raw://ddeb57c7ea151da4b52a95c6c12a225b54b80713c323821ea52f8c8ca295479c","dweb:/ipfs/QmZKwsNxRQFdQRjPsHP7RepfLtXDXhDEb3Qy2koPJdFoWG"]},"Vend.sol":{"keccak256":"0x4ab563e0d7bd503098b0772088c38b4a48b1e58cd4d5ae35311d080e4888f1d7","license":"AGPL-3.0-or-later","urls":["bzz-raw://6324109ccd635803305affce1f6b9aaed8b17c9e303a7f2c6ff56b34a26d1744","dweb:/ipfs/QmXKHQQDNPf4jqj7AhWDhdzPvhJYsLoUQP1xUV5SPxZZZj"]}},"version":1} +{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_controlToken","type":"address"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"bool","name":"_lock","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_idx","type":"uint256"},{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"TokenCreated","type":"event"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"create","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"getTokenByIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"mintFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"withdrawFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"Vend.sol":"ERC20Vend"},"evmVersion":"byzantium","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"GiftableToken.sol":{"keccak256":"0xaa3263856dd73d7bb1ec06b4ca38dd86ddd0771e8cb2ca47b7c1e3c69be9c14a","license":"AGPL-3.0-or-later","urls":["bzz-raw://ddeb57c7ea151da4b52a95c6c12a225b54b80713c323821ea52f8c8ca295479c","dweb:/ipfs/QmZKwsNxRQFdQRjPsHP7RepfLtXDXhDEb3Qy2koPJdFoWG"]},"Vend.sol":{"keccak256":"0xe5f94150fd2aad405a831ff66f8065089b0cbc54ae9e664c4b3a648a3bdc9f28","license":"AGPL-3.0-or-later","urls":["bzz-raw://a885de820226ed9223b1a9a04cb121d16dd55586ebed49dbf6de1589816cd0e1","dweb:/ipfs/QmQ2rTUanTaEheScpZKMv29qzSiXDzRj4eViFuVW7s35ji"]}},"version":1} diff --git a/python/erc20_vend/unittest/__init__.py b/python/erc20_vend/unittest/__init__.py @@ -1 +1,2 @@ from .base import TestVend +from .base import TestVendParams diff --git a/python/erc20_vend/unittest/base.py b/python/erc20_vend/unittest/base.py @@ -17,21 +17,45 @@ from erc20_vend import Vend logg = logging.getLogger(__name__) -class TestVend(TestGiftableToken): +class TestVendCore(TestGiftableToken): expire = 0 def setUp(self): - super(TestVend, self).setUp() + super(TestVendCore, self).setUp() + + self.alice = self.accounts[1] + self.bob = self.accounts[2] self.token_address = self.address + c = ERC20(self.chain_spec) + o = c.decimals(self.token_address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.token_decimals = c.parse_decimals(r) + + + def publish(self, lock=False, decimals=0): nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.constructor(self.accounts[0], self.token_address) + (tx_hash, o) = c.constructor(self.accounts[0], self.token_address, lock=lock, decimals=decimals) self.rpc.do(o) o = receipt(tx_hash) r = self.rpc.do(o) self.assertEqual(r['status'], 1) self.vend_address = to_checksum_address(r['contract_address']) logg.debug('published vend on address {} with hash {}'.format(self.vend_address, tx_hash)) + + +class TestVend(TestVendCore): + + def setUp(self): + super(TestVend, self).setUp() + self.publish() + + +class TestVendParams(TestVendCore): + + def setUp(self): + super(TestVendParams, self).setUp() + self.publish(lock=True, decimals=2) diff --git a/python/erc20_vend/vend.py b/python/erc20_vend/vend.py @@ -94,6 +94,32 @@ class Vend(TxFactory): return tx + def mint_for(self, contract_address, sender_address, token_address, value, tx_format=TxFormat.JSONRPC, id_generator=None): + enc = ABIContractEncoder() + enc.method('mintFor') + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.UINT256) + enc.address(token_address) + enc.uint256(value) + data = add_0x(enc.get()) + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format, id_generator=id_generator) + return tx + + + def withdraw_for(self, contract_address, sender_address, token_address, tx_format=TxFormat.JSONRPC, id_generator=None): + enc = ABIContractEncoder() + enc.method('withdrawFor') + enc.typ(ABIContractType.ADDRESS) + enc.address(token_address) + data = add_0x(enc.get()) + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format, id_generator=id_generator) + return tx + + def get_token(self, contract_address, token_idx, sender_address=ZERO_ADDRESS, id_generator=None): j = JSONRPCRequest(id_generator) o = j.template() @@ -111,7 +137,6 @@ class Vend(TxFactory): return o - def parse_token(self, v): dec = ABIContractDecoder() dec.typ(ABIContractType.ADDRESS) diff --git a/python/run_tests.sh b/python/run_tests.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -a +set -e +set -x +default_pythonpath=$PYTHONPATH:. +export PYTHONPATH=${default_pythonpath:-.} +>&2 echo using pythonpath $PYTHONPATH +for f in `ls tests/*.py`; do + python $f +done +set +x +set +e +set +a diff --git a/python/tests/test_base.py b/python/tests/test_base.py @@ -3,9 +3,13 @@ import unittest import logging import os from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.contract import ABIContractEncoder +from chainlib.eth.contract import ABIContractType +from chainlib.eth.tx import TxFormat from chainlib.eth.tx import receipt from eth_erc20 import ERC20 from giftable_erc20_token import GiftableToken +from hexathon import add_0x # local imports from erc20_vend.unittest import TestVend @@ -15,6 +19,7 @@ from erc20_vend import Vend logging.basicConfig(level=logging.DEBUG) logg = logging.getLogger() + class TestVendBase(TestVend): def test_create_token(self): @@ -41,6 +46,83 @@ class TestVendBase(TestVend): symbol = c.parse_symbol(r) self.assertEqual(symbol, 'FOOVEND') + + def test_vend_token(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.create(self.vend_address, self.accounts[0], 'foo vend', 'FOOVEND') + self.rpc.do(o) + + o = c.get_token(self.vend_address, 0, sender_address=self.accounts[0]) + r = self.rpc.do(o) + vended_token_address = c.parse_token(r) + + vend_amount = 100 + src_amount = vend_amount * (10 ** self.token_decimals) + c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.mint_to(self.token_address, self.accounts[0], self.alice, src_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.mint_for(self.vend_address, self.alice, vended_token_address, src_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.approve(self.token_address, self.alice, self.vend_address, src_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.mint_for(self.vend_address, self.alice, vended_token_address, src_amount + 1) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + + (tx_hash, o) = c.mint_for(self.vend_address, self.alice, vended_token_address, src_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + c = ERC20(self.chain_spec) + o = c.balance_of(vended_token_address, self.alice, sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, vend_amount) + + o = c.balance_of(self.token_address, self.alice, sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, 0) + + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.withdraw_for(self.vend_address, self.alice, vended_token_address) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + c = ERC20(self.chain_spec) + o = c.balance_of(vended_token_address, self.alice, sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, vend_amount) + + o = c.balance_of(self.token_address, self.alice, sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, src_amount) + if __name__ == '__main__': unittest.main() diff --git a/python/tests/test_lock.py b/python/tests/test_lock.py @@ -0,0 +1,113 @@ +# standard imports +import unittest +import logging +import os +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.contract import ABIContractEncoder +from chainlib.eth.contract import ABIContractType +from chainlib.eth.tx import TxFormat +from chainlib.eth.tx import receipt +from eth_erc20 import ERC20 +from giftable_erc20_token import GiftableToken +from hexathon import add_0x + +# local imports +from erc20_vend.unittest import TestVendParams +from erc20_vend import Vend + + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +class TestVendLocked(TestVendParams): + + def test_vend_token_lock(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.create(self.vend_address, self.accounts[0], 'foo vend', 'FOOVEND') + self.rpc.do(o) + + o = c.get_token(self.vend_address, 0, sender_address=self.accounts[0]) + r = self.rpc.do(o) + vended_token_address = c.parse_token(r) + + vend_amount = 100 + src_amount = vend_amount * (10 ** (self.token_decimals - 2)) + c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.mint_to(self.token_address, self.accounts[0], self.alice, src_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.mint_for(self.vend_address, self.alice, vended_token_address, src_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.approve(self.token_address, self.alice, self.vend_address, src_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.mint_for(self.vend_address, self.alice, vended_token_address, src_amount + 1) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + + (tx_hash, o) = c.mint_for(self.vend_address, self.alice, vended_token_address, src_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + c = ERC20(self.chain_spec) + o = c.balance_of(vended_token_address, self.alice, sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, vend_amount) + + o = c.balance_of(self.token_address, self.alice, sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, 0) + + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.withdraw_for(self.vend_address, self.alice, vended_token_address) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.approve(vended_token_address, self.alice, self.vend_address, vend_amount) + self.rpc.do(o) + + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.withdraw_for(self.vend_address, self.alice, vended_token_address) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + c = ERC20(self.chain_spec) + o = c.balance_of(vended_token_address, self.alice, sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, 0) + + o = c.balance_of(self.token_address, self.alice, sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, src_amount) + + +if __name__ == '__main__': + unittest.main() diff --git a/solidity/Vend.sol b/solidity/Vend.sol @@ -33,6 +33,9 @@ contract ERC20Vend { require(controlDecimals >= decimals); decimalDivisor = (10 ** (controlDecimals - _decimals)); + if (decimalDivisor == 0) { + decimalDivisor = 1; + } } function getTokenByIndex(uint256 _idx) public view returns(address) { @@ -56,7 +59,6 @@ contract ERC20Vend { GiftableToken l_token; bool r; bytes memory v; - uint256 l_balance; uint256 l_ratioedValue; require(_value < UINT256_MAX, "ERR_VALUE_TOO_HIGH"); @@ -67,7 +69,6 @@ contract ERC20Vend { l_token = GiftableToken(_token); require(used[msg.sender][address(_token)] == 0, "ERR_USED"); - l_balance = l_token.balanceOf(msg.sender); (r, v) = controlToken.call(abi.encodeWithSignature("transferFrom(address,address,uint256)", msg.sender, this, _value)); require(r, "ERR_TOKEN"); r = abi.decode(v, (bool)); @@ -79,7 +80,7 @@ contract ERC20Vend { l_ratioedValue = _value / decimalDivisor; } used[msg.sender][address(l_token)] += _value; - if (!l_token.mintTo(msg.sender, _value)) { + if (!l_token.mintTo(msg.sender, l_ratioedValue)) { revert("ERR_MINT"); } return _value; @@ -89,14 +90,23 @@ contract ERC20Vend { bool r; bytes memory v; uint256 l_balance; + uint256 l_vendBalance; l_balance = used[msg.sender][_token]; if (l_balance == 0) { return 0; } - checkLock(_token, msg.sender); + require(used[msg.sender][_token] < UINT256_MAX, "ERR_ALREADY_WITHDRAWN"); + l_vendBalance = checkLock(_token, msg.sender); used[msg.sender][_token] = UINT256_MAX; + if (l_vendBalance < UINT256_MAX) { + (r, v) = _token.call(abi.encodeWithSignature("transferFrom(address,address,uint256)", msg.sender, this, l_vendBalance)); + require(r, "ERR_TOKEN"); + r = abi.decode(v, (bool)); + require(r, "ERR_TOKEN_TRANSFER"); + } + (r, v) = controlToken.call(abi.encodeWithSignature("transfer(address,uint256)", msg.sender, l_balance)); require(r, "ERR_TOKEN"); r = abi.decode(v, (bool)); @@ -105,7 +115,9 @@ contract ERC20Vend { return l_balance; } - function checkLock(address _token, address _target) private returns (bool) { + // returns UINT256_MAX if lock is inactive + // reverts if locked and target does not have the original balance + function checkLock(address _token, address _target) private returns (uint256) { bool r; bytes memory v; uint256 l_currentBalance; @@ -116,8 +128,9 @@ contract ERC20Vend { require(r, "ERR_TOKEN"); l_currentBalance = abi.decode(v, (uint256)); l_heldBalance = used[_target][_token]; - require(l_currentBalance == l_heldBalance, "ERR_LOCKED"); + require(l_currentBalance * decimalDivisor == l_heldBalance, "ERR_LOCKED"); + return l_currentBalance; } - return true; + return UINT256_MAX; } }