erc20-vend

Create ERC20 tokens the can be minted by existing ERC20 token balance
Log | Files | Refs

commit f47e9b96e87de5c2dbc5343156ab5349c5d3e613
parent 4e5ca4f62f9ff6febbf2dd0898b7f5078c4faea1
Author: lash <dev@holbrook.no>
Date:   Sun,  7 May 2023 16:20:56 +0100

Remove non-lock alternative, add cleanup, create pre-mint alternative

Diffstat:
Mpython/erc20_vend/data/Vend.bin | 4++--
Mpython/erc20_vend/data/Vend.json | 2+-
Mpython/erc20_vend/data/Vend.metadata.json | 2+-
Mpython/erc20_vend/unittest/base.py | 4++--
Mpython/erc20_vend/vend.py | 12++++++------
Mpython/tests/test_base.py | 49++++++++++++++++++++++++++++++++++++++++++++++---
Mpython/tests/test_events.py | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Dpython/tests/test_lock.py | 107-------------------------------------------------------------------------------
Apython/tests/test_supply.py | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msolidity/Vend.sol | 132++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
10 files changed, 316 insertions(+), 157 deletions(-)

diff --git a/python/erc20_vend/data/Vend.bin b/python/erc20_vend/data/Vend.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b50604051620048633803806200486383398181016040528101906200003791906200039f565b60006060846000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600060156101000a81548160ff021916908360ff16021790555082600260006101000a81548160ff02191690831515021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000179919062000474565b6000604051808303816000865af19150503d8060008114620001b8576040519150601f19603f3d011682016040523d82523d6000602084013e620001bd565b606091505b5080925081935050508162000209576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200020090620004ee565b60405180910390fd5b808060200190518101906200021f919062000510565b600060146101000a81548160ff021916908360ff160217905550600060159054906101000a900460ff1660ff16600060149054906101000a900460ff1660ff1610156200026b57600080fd5b83600060149054906101000a900460ff1662000288919062000571565b600a6200029691906200070b565b600181905550600060015403620002af57600180819055505b50505050506200075c565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002ec82620002bf565b9050919050565b620002fe81620002df565b81146200030a57600080fd5b50565b6000815190506200031e81620002f3565b92915050565b600060ff82169050919050565b6200033c8162000324565b81146200034857600080fd5b50565b6000815190506200035c8162000331565b92915050565b60008115159050919050565b620003798162000362565b81146200038557600080fd5b50565b60008151905062000399816200036e565b92915050565b600080600060608486031215620003bb57620003ba620002ba565b5b6000620003cb868287016200030d565b9350506020620003de868287016200034b565b9250506040620003f18682870162000388565b9150509250925092565b600081519050919050565b600081905092915050565b60005b838110156200043157808201518184015260208101905062000414565b60008484015250505050565b60006200044a82620003fb565b62000456818562000406565b93506200046881856020860162000411565b80840191505092915050565b60006200048282846200043d565b915081905092915050565b600082825260208201905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b6000620004d66009836200048d565b9150620004e3826200049e565b602082019050919050565b600060208201905081810360008301526200050981620004c7565b9050919050565b600060208284031215620005295762000528620002ba565b5b600062000539848285016200034b565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200057e8262000324565b91506200058b8362000324565b9250828203905060ff811115620005a757620005a662000542565b5b92915050565b6000600282049050919050565b6000808291508390505b60018511156200060c57808604811115620005e457620005e362000542565b5b6001851615620005f45780820291505b80810290506200060485620005ad565b9450620005c4565b94509492505050565b600082620006275760019050620006fa565b81620006375760009050620006fa565b81600181146200065057600281146200065b5762000691565b6001915050620006fa565b60ff84111562000670576200066f62000542565b5b8360020a9150848211156200068a576200068962000542565b5b50620006fa565b5060208310610133831016604e8410600b8410161715620006cb5782820a905083811115620006c557620006c462000542565b5b620006fa565b620006da8484846001620005ba565b92509050818404811115620006f457620006f362000542565b5b81810290505b9392505050565b6000819050919050565b6000620007188262000701565b9150620007258362000324565b9250620007547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000615565b905092915050565b6140f7806200076c6000396000f3fe60806040523480156200001157600080fd5b50600436106200006f576000357c010000000000000000000000000000000000000000000000000000000090048063198e2b8a1462000074578063644b7a4314620000aa57806371e578dc14620000e05780639eca672c1462000116575b600080fd5b6200009260048036038101906200008c919062001269565b6200014c565b604051620000a191906200133c565b60405180910390f35b620000c86004803603810190620000c2919062001394565b6200025d565b604051620000d791906200133c565b60405180910390f35b620000fe6004803603810190620000f89190620013f7565b620002a8565b6040516200010d91906200143a565b60405180910390f35b6200013460048036038101906200012e9190620013f7565b6200098c565b6040516200014391906200143a565b60405180910390f35b60008060008087878787600060159054906101000a900460ff1660006040516200017690620011e3565b620001879695949392919062001526565b604051809103906000f080158015620001a4573d6000803e3d6000fd5b50925082915060038054905090506003839080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550807fc331dc3e37e2ab4d6e65d42a119ffdfab8481b9be24d26704f9f4b4a331d4dd0836040516200024791906200133c565b60405180910390a2819350505050949350505050565b60006003828154811062000276576200027562001585565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600080600060606000808694506000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541462000377576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200036e9062001604565b60405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1633604051602401620003c191906200133c565b6040516020818303038152906040527f70a08231000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516200044d91906200169f565b6000604051808303816000865af19150503d80600081146200048c576040519150601f19603f3d011682016040523d82523d6000602084013e62000491565b606091505b50809450819550505083620004dd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004d49062001708565b60405180910390fd5b82806020019051810190620004f3919062001741565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81106200055a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200055190620017c3565b60405180910390fd5b60008103620005725760009550505050505062000987565b600260009054906101000a900460ff1615620007d45760008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16333083604051602401620005d69392919062001846565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516200066291906200169f565b6000604051808303816000865af19150503d8060008114620006a1576040519150601f19603f3d011682016040523d82523d6000602084013e620006a6565b606091505b50809450819550505083620006f2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006e99062001708565b60405180910390fd5b82806020019051810190620007089190620018c0565b9350836200074d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007449062001942565b60405180910390fd5b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555062000876565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6000600154036200088a578091506200089d565b600154816200089a9190620019c2565b91505b8473ffffffffffffffffffffffffffffffffffffffff1663449a52f833846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401620008f6929190620019fa565b6020604051808303816000875af115801562000916573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200093c9190620018c0565b6200097e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009759062001a77565b60405180910390fd5b81955050505050505b919050565b6000806060600080600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205491506000820362000a2a57600094505050505062000f54565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541062000b0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b029062001ae9565b60405180910390fd5b62000b17863362000f59565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101562000d89578573ffffffffffffffffffffffffffffffffffffffff1633308360405160240162000c119392919062001846565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000c9d91906200169f565b6000604051808303816000865af19150503d806000811462000cdc576040519150601f19603f3d011682016040523d82523d6000602084013e62000ce1565b606091505b5080945081955050508362000d2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000d249062001708565b60405180910390fd5b8280602001905181019062000d439190620018c0565b93508362000d88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000d7f9062001942565b60405180910390fd5b5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16338360405160240162000dd5929190620019fa565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000e6191906200169f565b6000604051808303816000865af19150503d806000811462000ea0576040519150601f19603f3d011682016040523d82523d6000602084013e62000ea5565b606091505b5080945081955050508362000ef1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000ee89062001708565b60405180910390fd5b8280602001905181019062000f079190620018c0565b93508362000f4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000f439062001942565b60405180910390fd5b819450505050505b919050565b6000806060600080600260009054906101000a900460ff1615620011b5578673ffffffffffffffffffffffffffffffffffffffff168660405160240162000fa191906200133c565b6040516020818303038152906040527f70a08231000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516200102d91906200169f565b6000604051808303816000865af19150503d80600081146200106c576040519150601f19603f3d011682016040523d82523d6000602084013e62001071565b606091505b50809450819550505083620010bd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620010b49062001708565b60405180910390fd5b82806020019051810190620010d3919062001741565b9150600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050806001548362001165919062001b0b565b14620011a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200119f9062001ba6565b60405180910390fd5b81945050505050620011dd565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9450505050505b92915050565b6124f98062001bc983390190565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112620012235762001222620011fb565b5b8235905067ffffffffffffffff81111562001243576200124262001200565b5b60208301915083600182028301111562001262576200126162001205565b5b9250929050565b60008060008060408587031215620012865762001285620011f1565b5b600085013567ffffffffffffffff811115620012a757620012a6620011f6565b5b620012b5878288016200120a565b9450945050602085013567ffffffffffffffff811115620012db57620012da620011f6565b5b620012e9878288016200120a565b925092505092959194509250565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200132482620012f7565b9050919050565b620013368162001317565b82525050565b60006020820190506200135360008301846200132b565b92915050565b6000819050919050565b6200136e8162001359565b81146200137a57600080fd5b50565b6000813590506200138e8162001363565b92915050565b600060208284031215620013ad57620013ac620011f1565b5b6000620013bd848285016200137d565b91505092915050565b620013d18162001317565b8114620013dd57600080fd5b50565b600081359050620013f181620013c6565b92915050565b60006020828403121562001410576200140f620011f1565b5b60006200142084828501620013e0565b91505092915050565b620014348162001359565b82525050565b600060208201905062001451600083018462001429565b92915050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600062001496838562001457565b9350620014a583858462001468565b620014b08362001477565b840190509392505050565b600060ff82169050919050565b620014d381620014bb565b82525050565b6000819050919050565b6000819050919050565b60006200150e620015086200150284620014d9565b620014e3565b62001359565b9050919050565b6200152081620014ed565b82525050565b600060808201905081810360008301526200154381888a62001488565b905081810360208301526200155a81868862001488565b90506200156b6040830185620014c8565b6200157a606083018462001515565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552525f55534544000000000000000000000000000000000000000000000000600082015250565b6000620015ec60088362001457565b9150620015f982620015b4565b602082019050919050565b600060208201905081810360008301526200161f81620015dd565b9050919050565b600081519050919050565b600081905092915050565b60005b838110156200165c5780820151818401526020810190506200163f565b60008484015250505050565b6000620016758262001626565b62001681818562001631565b9350620016938185602086016200163c565b80840191505092915050565b6000620016ad828462001668565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b6000620016f060098362001457565b9150620016fd82620016b8565b602082019050919050565b600060208201905081810360008301526200172381620016e1565b9050919050565b6000815190506200173b8162001363565b92915050565b6000602082840312156200175a5762001759620011f1565b5b60006200176a848285016200172a565b91505092915050565b7f4552525f56414c55455f544f4f5f484947480000000000000000000000000000600082015250565b6000620017ab60128362001457565b9150620017b88262001773565b602082019050919050565b60006020820190508181036000830152620017de816200179c565b9050919050565b60006200180662001800620017fa84620012f7565b620014e3565b620012f7565b9050919050565b60006200181a82620017e5565b9050919050565b60006200182e826200180d565b9050919050565b620018408162001821565b82525050565b60006060820190506200185d60008301866200132b565b6200186c602083018562001835565b6200187b604083018462001429565b949350505050565b60008115159050919050565b6200189a8162001883565b8114620018a657600080fd5b50565b600081519050620018ba816200188f565b92915050565b600060208284031215620018d957620018d8620011f1565b5b6000620018e984828501620018a9565b91505092915050565b7f4552525f544f4b454e5f5452414e534645520000000000000000000000000000600082015250565b60006200192a60128362001457565b91506200193782620018f2565b602082019050919050565b600060208201905081810360008301526200195d816200191b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620019cf8262001359565b9150620019dc8362001359565b925082620019ef57620019ee62001964565b5b828204905092915050565b600060408201905062001a1160008301856200132b565b62001a20602083018462001429565b9392505050565b7f4552525f4d494e54000000000000000000000000000000000000000000000000600082015250565b600062001a5f60088362001457565b915062001a6c8262001a27565b602082019050919050565b6000602082019050818103600083015262001a928162001a50565b9050919050565b7f4552525f414c52454144595f57495448445241574e0000000000000000000000600082015250565b600062001ad160158362001457565b915062001ade8262001a99565b602082019050919050565b6000602082019050818103600083015262001b048162001ac2565b9050919050565b600062001b188262001359565b915062001b258362001359565b925082820262001b358162001359565b9150828204841483151762001b4f5762001b4e62001993565b5b5092915050565b7f4552525f4c4f434b454400000000000000000000000000000000000000000000600082015250565b600062001b8e600a8362001457565b915062001b9b8262001b56565b602082019050919050565b6000602082019050818103600083015262001bc18162001b7f565b905091905056fe60806040523480156200001157600080fd5b50604051620024f9380380620024f98339818101604052810190620000379190620002d3565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360029081620000889190620005ca565b5082600390816200009a9190620005ca565b5081600460006101000a81548160ff021916908360ff1602179055508060098190555050505050620006b1565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200013082620000e5565b810181811067ffffffffffffffff82111715620001525762000151620000f6565b5b80604052505050565b600062000167620000c7565b905062000175828262000125565b919050565b600067ffffffffffffffff821115620001985762000197620000f6565b5b620001a382620000e5565b9050602081019050919050565b60005b83811015620001d0578082015181840152602081019050620001b3565b60008484015250505050565b6000620001f3620001ed846200017a565b6200015b565b905082815260208101848484011115620002125762000211620000e0565b5b6200021f848285620001b0565b509392505050565b600082601f8301126200023f576200023e620000db565b5b815162000251848260208601620001dc565b91505092915050565b600060ff82169050919050565b62000272816200025a565b81146200027e57600080fd5b50565b600081519050620002928162000267565b92915050565b6000819050919050565b620002ad8162000298565b8114620002b957600080fd5b50565b600081519050620002cd81620002a2565b92915050565b60008060008060808587031215620002f057620002ef620000d1565b5b600085015167ffffffffffffffff811115620003115762000310620000d6565b5b6200031f8782880162000227565b945050602085015167ffffffffffffffff811115620003435762000342620000d6565b5b620003518782880162000227565b9350506040620003648782880162000281565b92505060606200037787828801620002bc565b91505092959194509250565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620003d657607f821691505b602082108103620003ec57620003eb6200038e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620004597fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000417565b62000465868362000417565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620004a8620004a26200049c8462000298565b6200047d565b62000298565b9050919050565b6000819050919050565b620004c48362000487565b620004dc620004d382620004af565b84845462000427565b825550505050565b600090565b620004f3620004e4565b62000500818484620004b9565b505050565b5b8181101562000528576200051c600082620004e9565b60018101905062000506565b5050565b601f82111562000577576200054181620003f2565b6200054c8462000407565b810160208510156200055c578190505b620005746200056b8562000407565b83018262000505565b50505b505050565b60008160020a8304905092915050565b60006200059f600019846008026200057c565b1980831691505092915050565b6000620005ba83836200058c565b9150826002028217905092915050565b620005d58262000383565b67ffffffffffffffff811115620005f157620005f0620000f6565b5b620005fd8254620003bd565b6200060a8282856200052c565b600060209050601f8311600181146200064257600084156200062d578287015190505b620006398582620005ac565b865550620006a9565b601f1984166200065286620003f2565b60005b828110156200067c5784890151825560018201915060208501945060208101905062000655565b868310156200069c578489015162000698601f8916826200058c565b8355505b6001600288020188555050505b505050505050565b611e3880620006c16000396000f3fe608060405234801561001057600080fd5b5060043610610175576000357c0100000000000000000000000000000000000000000000000000000000900480635f408c04116100e0578063a9059cbb11610099578063a9059cbb14610422578063b1cb0db314610452578063d89135cd14610470578063da2824a81461048e578063dd62ed3e146104be578063f2fde38b146104ee57610175565b80635f408c041461035e57806370a082311461037c5780638da5cb5b146103ac57806394d008ef146103ca57806395d89b41146103e6578063a2309ff81461040457610175565b8063313ce56711610132578063313ce5671461027657806342966c6814610294578063449a52f8146102c457806344d17187146102f457806344df8e70146103105780635ae06f7e1461032e57610175565b806301ffc9a71461017a57806306fdde03146101aa578063095ea7b3146101c857806318160ddd146101f857806323b872dd146102165780632b29ba2314610246575b600080fd5b610194600480360381019061018f919061178d565b61051e565b6040516101a191906117d5565b60405180910390f35b6101b2610768565b6040516101bf9190611880565b60405180910390f35b6101e260048036038101906101dd9190611936565b6107f6565b6040516101ef91906117d5565b60405180910390f35b610200610991565b60405161020d9190611985565b60405180910390f35b610230600480360381019061022b91906119a0565b6109a8565b60405161023d91906117d5565b60405180910390f35b610260600480360381019061025b91906119f3565b610cd0565b60405161026d91906117d5565b60405180910390f35b61027e610d7c565b60405161028b9190611a3c565b60405180910390f35b6102ae60048036038101906102a99190611a57565b610d8f565b6040516102bb91906117d5565b60405180910390f35b6102de60048036038101906102d99190611936565b610f51565b6040516102eb91906117d5565b60405180910390f35b61030e60048036038101906103099190611ae9565b6110dd565b005b61031861115b565b60405161032591906117d5565b60405180910390f35b610348600480360381019061034391906119f3565b6111aa565b60405161035591906117d5565b60405180910390f35b61036661129c565b6040516103739190611a3c565b60405180910390f35b610396600480360381019061039191906119f3565b61133a565b6040516103a39190611985565b60405180910390f35b6103b4611352565b6040516103c19190611b6c565b60405180910390f35b6103e460048036038101906103df9190611ae9565b611376565b005b6103ee611387565b6040516103fb9190611880565b60405180910390f35b61040c611415565b6040516104199190611985565b60405180910390f35b61043c60048036038101906104379190611936565b61141b565b60405161044991906117d5565b60405180910390f35b61045a61159a565b6040516104679190611985565b60405180910390f35b6104786115a0565b6040516104859190611985565b60405180910390f35b6104a860048036038101906104a391906119f3565b6115a6565b6040516104b591906117d5565b60405180910390f35b6104d860048036038101906104d39190611b87565b611662565b6040516104e59190611985565b60405180910390f35b610508600480360381019061050391906119f3565b611687565b60405161051591906117d5565b60405180910390f35b600063b61bc9417c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036105725760019050610763565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036105c45760019050610763565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106165760019050610763565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106685760019050610763565b63abe1f1f57c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106ba5760019050610763565b63b1110c1b7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361070c5760019050610763565b63841a0e947c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361075e5760019050610763565b600090505b919050565b6002805461077590611bf6565b80601f01602080910402602001604051908101604052809291908181526020018280546107a190611bf6565b80156107ee5780601f106107c3576101008083540402835291602001916107ee565b820191906000526020600020905b8154815290600101906020018083116107d157829003601f168201915b505050505081565b60008061080161129c565b60ff161461080e57600080fd5b60008211156108a1576000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146108a057600080fd5b5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161097f9190611985565b60405180910390a36001905092915050565b60006008546007546109a39190611c56565b905090565b6000806109b361129c565b60ff16146109c057600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610a4957600080fd5b81600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610a9557600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d9190611c56565b600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610bec9190611c56565b9250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c429190611c8a565b925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f93985604051610cbd9190611985565b60405180910390a4600190509392505050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680610d75575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050919050565b600460009054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1790611d0a565b60405180910390fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610ea2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9990611d76565b60405180910390fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610ef19190611c56565b925050819055508160086000828254610f0a9190611c8a565b925050819055507fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb82604051610f409190611985565b60405180910390a160019050919050565b6000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680610ff6575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610fff57600080fd5b81600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461104e9190611c8a565b9250508190555081600760008282546110679190611c8a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8846040516110cb9190611985565b60405180910390a36001905092915050565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461114b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114290611de2565b60405180910390fd5b61115483610d8f565b5050505050565b60006111a5600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d8f565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061123257508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61123b57600080fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600080600954036112b05760009050611337565b600a60009054906101000a900460ff16156112ce5760019050611337565b6009544210611332576001600a60006101000a81548160ff0219169083151502179055507ff80dbaea4785589e52984ca36a31de106adc77759539a5c7d92883bf49692fe9426040516113219190611985565b60405180910390a160029050611337565b600090505b90565b60056020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6113808484610f51565b5050505050565b6003805461139490611bf6565b80601f01602080910402602001604051908101604052809291908181526020018280546113c090611bf6565b801561140d5780601f106113e25761010080835404028352916020019161140d565b820191906000526020600020905b8154815290600101906020018083116113f057829003601f168201915b505050505081565b60075481565b60008061142661129c565b60ff161461143357600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561147f57600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546114ce9190611c56565b9250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546115249190611c8a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516115889190611985565b60405180910390a36001905092915050565b60095481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461160157600080fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6006602052816000526040600020602052806000526040600020600091509150505481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116e257600080fd5b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61176a81611735565b811461177557600080fd5b50565b60008135905061178781611761565b92915050565b6000602082840312156117a3576117a261172b565b5b60006117b184828501611778565b91505092915050565b60008115159050919050565b6117cf816117ba565b82525050565b60006020820190506117ea60008301846117c6565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561182a57808201518184015260208101905061180f565b60008484015250505050565b6000601f19601f8301169050919050565b6000611852826117f0565b61185c81856117fb565b935061186c81856020860161180c565b61187581611836565b840191505092915050565b6000602082019050818103600083015261189a8184611847565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006118cd826118a2565b9050919050565b6118dd816118c2565b81146118e857600080fd5b50565b6000813590506118fa816118d4565b92915050565b6000819050919050565b61191381611900565b811461191e57600080fd5b50565b6000813590506119308161190a565b92915050565b6000806040838503121561194d5761194c61172b565b5b600061195b858286016118eb565b925050602061196c85828601611921565b9150509250929050565b61197f81611900565b82525050565b600060208201905061199a6000830184611976565b92915050565b6000806000606084860312156119b9576119b861172b565b5b60006119c7868287016118eb565b93505060206119d8868287016118eb565b92505060406119e986828701611921565b9150509250925092565b600060208284031215611a0957611a0861172b565b5b6000611a17848285016118eb565b91505092915050565b600060ff82169050919050565b611a3681611a20565b82525050565b6000602082019050611a516000830184611a2d565b92915050565b600060208284031215611a6d57611a6c61172b565b5b6000611a7b84828501611921565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611aa957611aa8611a84565b5b8235905067ffffffffffffffff811115611ac657611ac5611a89565b5b602083019150836001820283011115611ae257611ae1611a8e565b5b9250929050565b60008060008060608587031215611b0357611b0261172b565b5b6000611b11878288016118eb565b9450506020611b2287828801611921565b935050604085013567ffffffffffffffff811115611b4357611b42611730565b5b611b4f87828801611a93565b925092505092959194509250565b611b66816118c2565b82525050565b6000602082019050611b816000830184611b5d565b92915050565b60008060408385031215611b9e57611b9d61172b565b5b6000611bac858286016118eb565b9250506020611bbd858286016118eb565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611c0e57607f821691505b602082108103611c2157611c20611bc7565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611c6182611900565b9150611c6c83611900565b9250828203905081811115611c8457611c83611c27565b5b92915050565b6000611c9582611900565b9150611ca083611900565b9250828201905080821115611cb857611cb7611c27565b5b92915050565b7f4552525f41434345535300000000000000000000000000000000000000000000600082015250565b6000611cf4600a836117fb565b9150611cff82611cbe565b602082019050919050565b60006020820190508181036000830152611d2381611ce7565b9050919050565b7f4552525f46554e44530000000000000000000000000000000000000000000000600082015250565b6000611d606009836117fb565b9150611d6b82611d2a565b602082019050919050565b60006020820190508181036000830152611d8f81611d53565b9050919050565b7f4552525f4e4f545f53454c460000000000000000000000000000000000000000600082015250565b6000611dcc600c836117fb565b9150611dd782611d96565b602082019050919050565b60006020820190508181036000830152611dfb81611dbf565b905091905056fea26469706673582212207c618c5e739ffaab5926ea597eb54f0122f3f64b626f5a26fb110c7779f25e7564736f6c63430008130033a26469706673582212203f837e5e03bed93f81034ba8d09e51af7b2e8951e451fd405cd086d8b9b5cc7f64736f6c63430008130033 -\ No newline at end of file +60806040523480156200001157600080fd5b50604051620054c1380380620054c1833981810160405281019062000037919062000547565b6000606084600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600160156101000a81548160ff021916908360ff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516200016291906200061c565b6000604051808303816000865af19150503d8060008114620001a1576040519150601f19603f3d011682016040523d82523d6000602084013e620001a6565b606091505b50809250819350505081620001f2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001e99062000696565b60405180910390fd5b80806020019051810190620002089190620006b8565b600160146101000a81548160ff021916908360ff160217905550600160159054906101000a900460ff1660ff16600160149054906101000a900460ff1660ff1610156200025457600080fd5b82620003d257600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f18160ddd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516200032591906200061c565b6000604051808303816000865af19150503d806000811462000364576040519150601f19603f3d011682016040523d82523d6000602084013e62000369565b606091505b50809250819350505081620003b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003ac9062000696565b60405180910390fd5b80806020019051810190620003cb919062000725565b6002819055505b83600160149054906101000a900460ff16620003ef919062000786565b600a620003fd919062000916565b600381905550600060035403620004175760016003819055505b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505062000967565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004948262000467565b9050919050565b620004a68162000487565b8114620004b257600080fd5b50565b600081519050620004c6816200049b565b92915050565b600060ff82169050919050565b620004e481620004cc565b8114620004f057600080fd5b50565b6000815190506200050481620004d9565b92915050565b60008115159050919050565b62000521816200050a565b81146200052d57600080fd5b50565b600081519050620005418162000516565b92915050565b60008060006060848603121562000563576200056262000462565b5b60006200057386828701620004b5565b93505060206200058686828701620004f3565b9250506040620005998682870162000530565b9150509250925092565b600081519050919050565b600081905092915050565b60005b83811015620005d9578082015181840152602081019050620005bc565b60008484015250505050565b6000620005f282620005a3565b620005fe8185620005ae565b935062000610818560208601620005b9565b80840191505092915050565b60006200062a8284620005e5565b915081905092915050565b600082825260208201905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b60006200067e60098362000635565b91506200068b8262000646565b602082019050919050565b60006020820190508181036000830152620006b1816200066f565b9050919050565b600060208284031215620006d157620006d062000462565b5b6000620006e184828501620004f3565b91505092915050565b6000819050919050565b620006ff81620006ea565b81146200070b57600080fd5b50565b6000815190506200071f81620006f4565b92915050565b6000602082840312156200073e576200073d62000462565b5b60006200074e848285016200070e565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200079382620004cc565b9150620007a083620004cc565b9250828203905060ff811115620007bc57620007bb62000757565b5b92915050565b6000600282049050919050565b6000808291508390505b60018511156200082157808604811115620007f957620007f862000757565b5b6001851615620008095780820291505b80810290506200081985620007c2565b9450620007d9565b94509492505050565b6000826200083c57600190506200090f565b816200084c57600090506200090f565b81600181146200086557600281146200087057620008a6565b60019150506200090f565b60ff84111562000885576200088462000757565b5b8360020a9150848211156200089f576200089e62000757565b5b506200090f565b5060208310610133831016604e8410600b8410161715620008e05782820a905083811115620008da57620008d962000757565b5b6200090f565b620008ef8484846001620007cf565b9250905081840481111562000909576200090862000757565b5b81810290505b9392505050565b60006200092382620006ea565b91506200093083620004cc565b92506200095f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846200082a565b905092915050565b614b4a80620009776000396000f3fe60806040523480156200001157600080fd5b5060043610620000bd576000357c0100000000000000000000000000000000000000000000000000000000900480632b29ba23116200008c5780632b29ba23146200019a5780635ae06f7e14620001d0578063644b7a4314620002065780639eca672c146200023c578063da2824a8146200027257620000bd565b806301ffc9a714620000c257806314d943b014620000f8578063169b2623146200012e578063198e2b8a1462000164575b600080fd5b620000e06004803603810190620000da919062001acf565b620002a8565b604051620000ef919062001b1e565b60405180910390f35b62000116600480360381019062000110919062001ba0565b6200035c565b60405162000125919062001bed565b60405180910390f35b6200014c600480360381019062000146919062001ba0565b62000b3b565b6040516200015b919062001bed565b60405180910390f35b6200018260048036038101906200017c919062001c78565b62000d75565b60405162000191919062001d17565b60405180910390f35b620001b86004803603810190620001b2919062001ba0565b62000f38565b604051620001c7919062001b1e565b60405180910390f35b620001ee6004803603810190620001e8919062001ba0565b62000fe5565b604051620001fd919062001b1e565b60405180910390f35b6200022460048036038101906200021e919062001d65565b620010d9565b60405162000233919062001d17565b60405180910390f35b6200025a600480360381019062000254919062001ba0565b62001124565b60405162000269919062001bed565b60405180910390f35b6200029060048036038101906200028a919062001ba0565b62001757565b6040516200029f919062001b1e565b60405180910390f35b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603620002fe576001905062000357565b63abe1f1f57c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160362000352576001905062000357565b600090505b919050565b600080600060606000808694506000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146200042b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004229062001df8565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163360405160240162000477919062001d17565b6040516020818303038152906040527f70a08231000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000503919062001e93565b6000604051808303816000865af19150503d806000811462000542576040519150601f19603f3d011682016040523d82523d6000602084013e62000547565b606091505b5080945081955050508362000593576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200058a9062001efc565b60405180910390fd5b82806020019051810190620005a9919062001f35565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811062000610576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006079062001fb7565b60405180910390fd5b60008103620006285760009550505050505062000b36565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16333083604051602401620006789392919062002044565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000704919062001e93565b6000604051808303816000865af19150503d806000811462000743576040519150601f19603f3d011682016040523d82523d6000602084013e62000748565b606091505b5080945081955050508362000794576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200078b9062001efc565b60405180910390fd5b82806020019051810190620007aa9190620020b2565b935083620007ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007e69062002134565b60405180910390fd5b80600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600060035403620008845780915062000897565b60035481620008949190620021b4565b91505b60006002540362000989578473ffffffffffffffffffffffffffffffffffffffff1663449a52f833846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401620008fb929190620021ec565b6020604051808303816000875af11580156200091b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009419190620020b2565b62000983576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200097a9062002269565b60405180910390fd5b62000b2d565b8673ffffffffffffffffffffffffffffffffffffffff163383604051602401620009b5929190620021ec565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000a41919062001e93565b6000604051808303816000865af19150503d806000811462000a80576040519150601f19603f3d011682016040523d82523d6000602084013e62000a85565b606091505b5080945081955050508362000ad1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000ac89062001efc565b60405180910390fd5b8280602001905181019062000ae79190620020b2565b93508362000b2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b2390620022db565b60405180910390fd5b5b81955050505050505b919050565b60008060606000600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508473ffffffffffffffffffffffffffffffffffffffff168160405160240162000bae919062001bed565b6040516020818303038152906040527f42966c68000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162000c3a919062001e93565b6000604051808303816000865af19150503d806000811462000c79576040519150601f19603f3d011682016040523d82523d6000602084013e62000c7e565b606091505b5080935081945050508262000cca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000cc19062001efc565b60405180910390fd5b8180602001905181019062000ce09190620020b2565b92508262000d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000d1c906200234d565b60405180910390fd5b6000600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550809350505050919050565b60008060008087878787600160159054906101000a900460ff16600060405162000d9f9062001a5a565b62000db09695949392919062002423565b604051809103906000f08015801562000dcd573d6000803e3d6000fd5b50925082915060058054905090506005839080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600254111562000eed578273ffffffffffffffffffffffffffffffffffffffff1663449a52f8306002546040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040162000ea5929190620021ec565b6020604051808303816000875af115801562000ec5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000eeb9190620020b2565b505b600254817f0f91f79b60765ed60c8537a0c2f417bfc1ab0a46df716a76bc7ba5130529898f8460405162000f22919062001d17565b60405180910390a3819350505050949350505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff168062000fde575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806200106e57508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6200107857600080fd5b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600060058281548110620010f257620010f162002482565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000806060600080600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054915060008203620011c257600094505050505062001752565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410620012a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200129a9062002501565b60405180910390fd5b620012af863362001814565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81036200138857600094505050505062001752565b8573ffffffffffffffffffffffffffffffffffffffff16333083604051602401620013b69392919062002044565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405162001442919062001e93565b6000604051808303816000865af19150503d806000811462001481576040519150601f19603f3d011682016040523d82523d6000602084013e62001486565b606091505b50809450819550505083620014d2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620014c99062001efc565b60405180910390fd5b82806020019051810190620014e89190620020b2565b9350836200152d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620015249062002134565b60405180910390fd5b80600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546200157e919062002523565b92505081905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163383604051602401620015d3929190620021ec565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516200165f919062001e93565b6000604051808303816000865af19150503d80600081146200169e576040519150601f19603f3d011682016040523d82523d6000602084013e620016a3565b606091505b50809450819550505083620016ef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620016e69062001efc565b60405180910390fd5b82806020019051810190620017059190620020b2565b9350836200174a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620017419062002134565b60405180910390fd5b819450505050505b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614620017b357600080fd5b6001600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b60008060606000808673ffffffffffffffffffffffffffffffffffffffff168660405160240162001846919062001d17565b6040516020818303038152906040527f70a08231000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051620018d2919062001e93565b6000604051808303816000865af19150503d806000811462001911576040519150601f19603f3d011682016040523d82523d6000602084013e62001916565b606091505b5080945081955050508362001962576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620019599062001efc565b60405180910390fd5b8280602001905181019062001978919062001f35565b9150600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050806003548362001a0a91906200255e565b1462001a4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162001a4490620025f9565b60405180910390fd5b8194505050505092915050565b6124f9806200261c83390190565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62001aa98162001a72565b811462001ab557600080fd5b50565b60008135905062001ac98162001a9e565b92915050565b60006020828403121562001ae85762001ae762001a68565b5b600062001af88482850162001ab8565b91505092915050565b60008115159050919050565b62001b188162001b01565b82525050565b600060208201905062001b35600083018462001b0d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062001b688262001b3b565b9050919050565b62001b7a8162001b5b565b811462001b8657600080fd5b50565b60008135905062001b9a8162001b6f565b92915050565b60006020828403121562001bb95762001bb862001a68565b5b600062001bc98482850162001b89565b91505092915050565b6000819050919050565b62001be78162001bd2565b82525050565b600060208201905062001c04600083018462001bdc565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011262001c325762001c3162001c0a565b5b8235905067ffffffffffffffff81111562001c525762001c5162001c0f565b5b60208301915083600182028301111562001c715762001c7062001c14565b5b9250929050565b6000806000806040858703121562001c955762001c9462001a68565b5b600085013567ffffffffffffffff81111562001cb65762001cb562001a6d565b5b62001cc48782880162001c19565b9450945050602085013567ffffffffffffffff81111562001cea5762001ce962001a6d565b5b62001cf88782880162001c19565b925092505092959194509250565b62001d118162001b5b565b82525050565b600060208201905062001d2e600083018462001d06565b92915050565b62001d3f8162001bd2565b811462001d4b57600080fd5b50565b60008135905062001d5f8162001d34565b92915050565b60006020828403121562001d7e5762001d7d62001a68565b5b600062001d8e8482850162001d4e565b91505092915050565b600082825260208201905092915050565b7f4552525f55534544000000000000000000000000000000000000000000000000600082015250565b600062001de060088362001d97565b915062001ded8262001da8565b602082019050919050565b6000602082019050818103600083015262001e138162001dd1565b9050919050565b600081519050919050565b600081905092915050565b60005b8381101562001e5057808201518184015260208101905062001e33565b60008484015250505050565b600062001e698262001e1a565b62001e75818562001e25565b935062001e8781856020860162001e30565b80840191505092915050565b600062001ea1828462001e5c565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b600062001ee460098362001d97565b915062001ef18262001eac565b602082019050919050565b6000602082019050818103600083015262001f178162001ed5565b9050919050565b60008151905062001f2f8162001d34565b92915050565b60006020828403121562001f4e5762001f4d62001a68565b5b600062001f5e8482850162001f1e565b91505092915050565b7f4552525f56414c55455f544f4f5f484947480000000000000000000000000000600082015250565b600062001f9f60128362001d97565b915062001fac8262001f67565b602082019050919050565b6000602082019050818103600083015262001fd28162001f90565b9050919050565b6000819050919050565b60006200200462001ffe62001ff88462001b3b565b62001fd9565b62001b3b565b9050919050565b6000620020188262001fe3565b9050919050565b60006200202c826200200b565b9050919050565b6200203e816200201f565b82525050565b60006060820190506200205b600083018662001d06565b6200206a602083018562002033565b62002079604083018462001bdc565b949350505050565b6200208c8162001b01565b81146200209857600080fd5b50565b600081519050620020ac8162002081565b92915050565b600060208284031215620020cb57620020ca62001a68565b5b6000620020db848285016200209b565b91505092915050565b7f4552525f544f4b454e5f5452414e534645520000000000000000000000000000600082015250565b60006200211c60128362001d97565b91506200212982620020e4565b602082019050919050565b600060208201905081810360008301526200214f816200210d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620021c18262001bd2565b9150620021ce8362001bd2565b925082620021e157620021e062002156565b5b828204905092915050565b600060408201905062002203600083018562001d06565b62002212602083018462001bdc565b9392505050565b7f4552525f4d494e54000000000000000000000000000000000000000000000000600082015250565b60006200225160088362001d97565b91506200225e8262002219565b602082019050919050565b60006020820190508181036000830152620022848162002242565b9050919050565b7f4552525f56454e445f544f4b454e5f5452414e53464552000000000000000000600082015250565b6000620022c360178362001d97565b9150620022d0826200228b565b602082019050919050565b60006020820190508181036000830152620022f681620022b4565b9050919050565b7f4552525f544f4b454e5f4255524e000000000000000000000000000000000000600082015250565b600062002335600e8362001d97565b91506200234282620022fd565b602082019050919050565b60006020820190508181036000830152620023688162002326565b9050919050565b82818337600083830152505050565b6000601f19601f8301169050919050565b60006200239d838562001d97565b9350620023ac8385846200236f565b620023b7836200237e565b840190509392505050565b600060ff82169050919050565b620023da81620023c2565b82525050565b6000819050919050565b60006200240b62002405620023ff84620023e0565b62001fd9565b62001bd2565b9050919050565b6200241d81620023ea565b82525050565b600060808201905081810360008301526200244081888a6200238f565b90508181036020830152620024578186886200238f565b9050620024686040830185620023cf565b62002477606083018462002412565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552525f414c52454144595f57495448445241574e0000000000000000000000600082015250565b6000620024e960158362001d97565b9150620024f682620024b1565b602082019050919050565b600060208201905081810360008301526200251c81620024da565b9050919050565b6000620025308262001bd2565b91506200253d8362001bd2565b925082820190508082111562002558576200255762002185565b5b92915050565b60006200256b8262001bd2565b9150620025788362001bd2565b9250828202620025888162001bd2565b91508282048414831517620025a257620025a162002185565b5b5092915050565b7f4552525f4c4f434b454400000000000000000000000000000000000000000000600082015250565b6000620025e1600a8362001d97565b9150620025ee82620025a9565b602082019050919050565b600060208201905081810360008301526200261481620025d2565b905091905056fe60806040523480156200001157600080fd5b50604051620024f9380380620024f98339818101604052810190620000379190620002d3565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360029081620000889190620005ca565b5082600390816200009a9190620005ca565b5081600460006101000a81548160ff021916908360ff1602179055508060098190555050505050620006b1565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200013082620000e5565b810181811067ffffffffffffffff82111715620001525762000151620000f6565b5b80604052505050565b600062000167620000c7565b905062000175828262000125565b919050565b600067ffffffffffffffff821115620001985762000197620000f6565b5b620001a382620000e5565b9050602081019050919050565b60005b83811015620001d0578082015181840152602081019050620001b3565b60008484015250505050565b6000620001f3620001ed846200017a565b6200015b565b905082815260208101848484011115620002125762000211620000e0565b5b6200021f848285620001b0565b509392505050565b600082601f8301126200023f576200023e620000db565b5b815162000251848260208601620001dc565b91505092915050565b600060ff82169050919050565b62000272816200025a565b81146200027e57600080fd5b50565b600081519050620002928162000267565b92915050565b6000819050919050565b620002ad8162000298565b8114620002b957600080fd5b50565b600081519050620002cd81620002a2565b92915050565b60008060008060808587031215620002f057620002ef620000d1565b5b600085015167ffffffffffffffff811115620003115762000310620000d6565b5b6200031f8782880162000227565b945050602085015167ffffffffffffffff811115620003435762000342620000d6565b5b620003518782880162000227565b9350506040620003648782880162000281565b92505060606200037787828801620002bc565b91505092959194509250565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620003d657607f821691505b602082108103620003ec57620003eb6200038e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620004597fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000417565b62000465868362000417565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620004a8620004a26200049c8462000298565b6200047d565b62000298565b9050919050565b6000819050919050565b620004c48362000487565b620004dc620004d382620004af565b84845462000427565b825550505050565b600090565b620004f3620004e4565b62000500818484620004b9565b505050565b5b8181101562000528576200051c600082620004e9565b60018101905062000506565b5050565b601f82111562000577576200054181620003f2565b6200054c8462000407565b810160208510156200055c578190505b620005746200056b8562000407565b83018262000505565b50505b505050565b60008160020a8304905092915050565b60006200059f600019846008026200057c565b1980831691505092915050565b6000620005ba83836200058c565b9150826002028217905092915050565b620005d58262000383565b67ffffffffffffffff811115620005f157620005f0620000f6565b5b620005fd8254620003bd565b6200060a8282856200052c565b600060209050601f8311600181146200064257600084156200062d578287015190505b620006398582620005ac565b865550620006a9565b601f1984166200065286620003f2565b60005b828110156200067c5784890151825560018201915060208501945060208101905062000655565b868310156200069c578489015162000698601f8916826200058c565b8355505b6001600288020188555050505b505050505050565b611e3880620006c16000396000f3fe608060405234801561001057600080fd5b5060043610610175576000357c0100000000000000000000000000000000000000000000000000000000900480635f408c04116100e0578063a9059cbb11610099578063a9059cbb14610422578063b1cb0db314610452578063d89135cd14610470578063da2824a81461048e578063dd62ed3e146104be578063f2fde38b146104ee57610175565b80635f408c041461035e57806370a082311461037c5780638da5cb5b146103ac57806394d008ef146103ca57806395d89b41146103e6578063a2309ff81461040457610175565b8063313ce56711610132578063313ce5671461027657806342966c6814610294578063449a52f8146102c457806344d17187146102f457806344df8e70146103105780635ae06f7e1461032e57610175565b806301ffc9a71461017a57806306fdde03146101aa578063095ea7b3146101c857806318160ddd146101f857806323b872dd146102165780632b29ba2314610246575b600080fd5b610194600480360381019061018f919061178d565b61051e565b6040516101a191906117d5565b60405180910390f35b6101b2610768565b6040516101bf9190611880565b60405180910390f35b6101e260048036038101906101dd9190611936565b6107f6565b6040516101ef91906117d5565b60405180910390f35b610200610991565b60405161020d9190611985565b60405180910390f35b610230600480360381019061022b91906119a0565b6109a8565b60405161023d91906117d5565b60405180910390f35b610260600480360381019061025b91906119f3565b610cd0565b60405161026d91906117d5565b60405180910390f35b61027e610d7c565b60405161028b9190611a3c565b60405180910390f35b6102ae60048036038101906102a99190611a57565b610d8f565b6040516102bb91906117d5565b60405180910390f35b6102de60048036038101906102d99190611936565b610f51565b6040516102eb91906117d5565b60405180910390f35b61030e60048036038101906103099190611ae9565b6110dd565b005b61031861115b565b60405161032591906117d5565b60405180910390f35b610348600480360381019061034391906119f3565b6111aa565b60405161035591906117d5565b60405180910390f35b61036661129c565b6040516103739190611a3c565b60405180910390f35b610396600480360381019061039191906119f3565b61133a565b6040516103a39190611985565b60405180910390f35b6103b4611352565b6040516103c19190611b6c565b60405180910390f35b6103e460048036038101906103df9190611ae9565b611376565b005b6103ee611387565b6040516103fb9190611880565b60405180910390f35b61040c611415565b6040516104199190611985565b60405180910390f35b61043c60048036038101906104379190611936565b61141b565b60405161044991906117d5565b60405180910390f35b61045a61159a565b6040516104679190611985565b60405180910390f35b6104786115a0565b6040516104859190611985565b60405180910390f35b6104a860048036038101906104a391906119f3565b6115a6565b6040516104b591906117d5565b60405180910390f35b6104d860048036038101906104d39190611b87565b611662565b6040516104e59190611985565b60405180910390f35b610508600480360381019061050391906119f3565b611687565b60405161051591906117d5565b60405180910390f35b600063b61bc9417c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036105725760019050610763565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036105c45760019050610763565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106165760019050610763565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106685760019050610763565b63abe1f1f57c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106ba5760019050610763565b63b1110c1b7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361070c5760019050610763565b63841a0e947c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361075e5760019050610763565b600090505b919050565b6002805461077590611bf6565b80601f01602080910402602001604051908101604052809291908181526020018280546107a190611bf6565b80156107ee5780601f106107c3576101008083540402835291602001916107ee565b820191906000526020600020905b8154815290600101906020018083116107d157829003601f168201915b505050505081565b60008061080161129c565b60ff161461080e57600080fd5b60008211156108a1576000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146108a057600080fd5b5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161097f9190611985565b60405180910390a36001905092915050565b60006008546007546109a39190611c56565b905090565b6000806109b361129c565b60ff16146109c057600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610a4957600080fd5b81600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610a9557600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d9190611c56565b600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610bec9190611c56565b9250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c429190611c8a565b925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f93985604051610cbd9190611985565b60405180910390a4600190509392505050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680610d75575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050919050565b600460009054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1790611d0a565b60405180910390fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610ea2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9990611d76565b60405180910390fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610ef19190611c56565b925050819055508160086000828254610f0a9190611c8a565b925050819055507fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb82604051610f409190611985565b60405180910390a160019050919050565b6000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680610ff6575060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610fff57600080fd5b81600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461104e9190611c8a565b9250508190555081600760008282546110679190611c8a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8846040516110cb9190611985565b60405180910390a36001905092915050565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461114b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114290611de2565b60405180910390fd5b61115483610d8f565b5050505050565b60006111a5600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d8f565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061123257508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61123b57600080fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600080600954036112b05760009050611337565b600a60009054906101000a900460ff16156112ce5760019050611337565b6009544210611332576001600a60006101000a81548160ff0219169083151502179055507ff80dbaea4785589e52984ca36a31de106adc77759539a5c7d92883bf49692fe9426040516113219190611985565b60405180910390a160029050611337565b600090505b90565b60056020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6113808484610f51565b5050505050565b6003805461139490611bf6565b80601f01602080910402602001604051908101604052809291908181526020018280546113c090611bf6565b801561140d5780601f106113e25761010080835404028352916020019161140d565b820191906000526020600020905b8154815290600101906020018083116113f057829003601f168201915b505050505081565b60075481565b60008061142661129c565b60ff161461143357600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561147f57600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546114ce9190611c56565b9250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546115249190611c8a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516115889190611985565b60405180910390a36001905092915050565b60095481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461160157600080fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6006602052816000526040600020602052806000526040600020600091509150505481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116e257600080fd5b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61176a81611735565b811461177557600080fd5b50565b60008135905061178781611761565b92915050565b6000602082840312156117a3576117a261172b565b5b60006117b184828501611778565b91505092915050565b60008115159050919050565b6117cf816117ba565b82525050565b60006020820190506117ea60008301846117c6565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561182a57808201518184015260208101905061180f565b60008484015250505050565b6000601f19601f8301169050919050565b6000611852826117f0565b61185c81856117fb565b935061186c81856020860161180c565b61187581611836565b840191505092915050565b6000602082019050818103600083015261189a8184611847565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006118cd826118a2565b9050919050565b6118dd816118c2565b81146118e857600080fd5b50565b6000813590506118fa816118d4565b92915050565b6000819050919050565b61191381611900565b811461191e57600080fd5b50565b6000813590506119308161190a565b92915050565b6000806040838503121561194d5761194c61172b565b5b600061195b858286016118eb565b925050602061196c85828601611921565b9150509250929050565b61197f81611900565b82525050565b600060208201905061199a6000830184611976565b92915050565b6000806000606084860312156119b9576119b861172b565b5b60006119c7868287016118eb565b93505060206119d8868287016118eb565b92505060406119e986828701611921565b9150509250925092565b600060208284031215611a0957611a0861172b565b5b6000611a17848285016118eb565b91505092915050565b600060ff82169050919050565b611a3681611a20565b82525050565b6000602082019050611a516000830184611a2d565b92915050565b600060208284031215611a6d57611a6c61172b565b5b6000611a7b84828501611921565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611aa957611aa8611a84565b5b8235905067ffffffffffffffff811115611ac657611ac5611a89565b5b602083019150836001820283011115611ae257611ae1611a8e565b5b9250929050565b60008060008060608587031215611b0357611b0261172b565b5b6000611b11878288016118eb565b9450506020611b2287828801611921565b935050604085013567ffffffffffffffff811115611b4357611b42611730565b5b611b4f87828801611a93565b925092505092959194509250565b611b66816118c2565b82525050565b6000602082019050611b816000830184611b5d565b92915050565b60008060408385031215611b9e57611b9d61172b565b5b6000611bac858286016118eb565b9250506020611bbd858286016118eb565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611c0e57607f821691505b602082108103611c2157611c20611bc7565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611c6182611900565b9150611c6c83611900565b9250828203905081811115611c8457611c83611c27565b5b92915050565b6000611c9582611900565b9150611ca083611900565b9250828201905080821115611cb857611cb7611c27565b5b92915050565b7f4552525f41434345535300000000000000000000000000000000000000000000600082015250565b6000611cf4600a836117fb565b9150611cff82611cbe565b602082019050919050565b60006020820190508181036000830152611d2381611ce7565b9050919050565b7f4552525f46554e44530000000000000000000000000000000000000000000000600082015250565b6000611d606009836117fb565b9150611d6b82611d2a565b602082019050919050565b60006020820190508181036000830152611d8f81611d53565b9050919050565b7f4552525f4e4f545f53454c460000000000000000000000000000000000000000600082015250565b6000611dcc600c836117fb565b9150611dd782611d96565b602082019050919050565b60006020820190508181036000830152611dfb81611dbf565b905091905056fea26469706673582212207c618c5e739ffaab5926ea597eb54f0122f3f64b626f5a26fb110c7779f25e7564736f6c63430008130033a2646970667358221220d718193743c1066a5d8ff85894b8613f5e643171e05d91cd0fce384ef6275fae64736f6c63430008130033 +\ No newline at end of file diff --git a/python/erc20_vend/data/Vend.json b/python/erc20_vend/data/Vend.json @@ -1 +1 @@ -[{"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"}],"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"}] +[{"inputs":[{"internalType":"address","name":"_controlToken","type":"address"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"bool","name":"_mint","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_idx","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_supply","type":"uint256"},{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"TokenCreated","type":"event"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"addWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"clean","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"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":"address","name":"_minter","type":"address"}],"name":"deleteWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"_minter","type":"address"}],"name":"isWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"withdrawFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] 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"}],"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":"0x7b5aea312830bd875fee47ab596648fb51a10bc4d27f65e2bb7bcc63d43e9496","license":"AGPL-3.0-or-later","urls":["bzz-raw://7692c21373cf253573df268aa6b80c9d83228345391bea4fbca14a0cedb508bb","dweb:/ipfs/QmbUxUuaz6ECoEKs99jzWcyvwjE111w9W8UN4qNEL8NwnH"]}},"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":"_mint","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_idx","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_supply","type":"uint256"},{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"TokenCreated","type":"event"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"addWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"clean","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"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":"address","name":"_minter","type":"address"}],"name":"deleteWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"_minter","type":"address"}],"name":"isWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","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":"0x64d539d4d363060e1ea38eb7812ed1786bfce0996e2571ed27aa3dea379cfbec","license":"AGPL-3.0-or-later","urls":["bzz-raw://59d229040c8fb38304113cfd4b40d6a0a87704e88df975a624f1775ffaff548b","dweb:/ipfs/QmNxar5xMx4YDqaHLtbCoKjJ9DRzRzCfnQtgHZhcPMW1En"]}},"version":1} diff --git a/python/erc20_vend/unittest/base.py b/python/erc20_vend/unittest/base.py @@ -35,10 +35,10 @@ class TestVendCore(TestGiftableToken): self.token_decimals = c.parse_decimals(r) - def publish(self, lock=False, decimals=0): + def publish(self, mint=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, lock=lock, decimals=decimals) + (tx_hash, o) = c.constructor(self.accounts[0], self.token_address, mint=mint, decimals=decimals) self.rpc.do(o) o = receipt(tx_hash) r = self.rpc.do(o) diff --git a/python/erc20_vend/vend.py b/python/erc20_vend/vend.py @@ -36,20 +36,20 @@ class Vend(TxFactory): __abi = None __bytecode = None - def constructor(self, sender_address, token_address, decimals=0, lock=False, tx_format=TxFormat.JSONRPC, version=None): - code = self.cargs(token_address, decimals=decimals, lock=lock, version=version) + def constructor(self, sender_address, token_address, decimals=0, mint=False, tx_format=TxFormat.JSONRPC, version=None): + code = self.cargs(token_address, decimals=decimals, mint=mint, version=version) tx = self.template(sender_address, None, use_nonce=True) tx = self.set_code(tx, code) return self.finalize(tx, tx_format) @staticmethod - def cargs(token_address, decimals=0, lock=False, version=None): + def cargs(token_address, decimals=0, mint=False, version=None): code = Vend.bytecode(version=version) enc = ABIContractEncoder() enc.address(token_address) enc.uintn(decimals, 8) - enc.bool(lock) + enc.bool(mint) args = enc.get() code += args logg.debug('constructor code: ' + args) @@ -94,9 +94,9 @@ class Vend(TxFactory): return tx - def mint_for(self, contract_address, sender_address, token_address, tx_format=TxFormat.JSONRPC, id_generator=None): + def get_for(self, contract_address, sender_address, token_address, tx_format=TxFormat.JSONRPC, id_generator=None): enc = ABIContractEncoder() - enc.method('mintFor') + enc.method('getFor') enc.typ(ABIContractType.ADDRESS) enc.address(token_address) data = add_0x(enc.get()) diff --git a/python/tests/test_base.py b/python/tests/test_base.py @@ -42,7 +42,6 @@ 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) @@ -54,7 +53,7 @@ class TestVendBase(TestVend): vended_token_address = c.parse_token(r) vend_amount = 100 - src_amount = vend_amount * (10 ** self.token_decimals) + 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) @@ -64,7 +63,21 @@ class TestVendBase(TestVend): 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) + (tx_hash, o) = c.get_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(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.get_for(self.vend_address, self.alice, vended_token_address) self.rpc.do(o) o = receipt(tx_hash) r = self.rpc.do(o) @@ -79,8 +92,38 @@ class TestVendBase(TestVend): 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/python/tests/test_events.py b/python/tests/test_events.py @@ -11,7 +11,7 @@ from giftable_erc20_token import GiftableToken from hexathon import same as same_hex # local imports -from erc20_vend.unittest import TestVend +from erc20_vend.unittest.base import TestVendCore from erc20_vend import Vend @@ -19,9 +19,10 @@ logging.basicConfig(level=logging.DEBUG) logg = logging.getLogger() -class TestVendBase(TestVend): +class TestVendBase(TestVendCore): def test_create_token_event(self): + self.publish(mint=True) 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') @@ -37,13 +38,16 @@ class TestVendBase(TestVend): dec = ABIContractLogDecoder() dec.topic('TokenCreated') dec.typ(ABIContractType.UINT256) + dec.typ(ABIContractType.UINT256) dec.typ(ABIContractType.ADDRESS) dec.apply(rlog['topics'], [rlog['data']]) self.assertEqual(int(dec.contents[0], 16), 0) - self.assertEqual(int(dec.contents[1], 16), int(vended_token_address, 16)) + self.assertEqual(int(dec.contents[1], 16), 0) + self.assertEqual(int(dec.contents[2], 16), int(vended_token_address, 16)) def test_mint_event(self): + self.publish(mint=True) 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') @@ -61,10 +65,11 @@ class TestVendBase(TestVend): 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) + (tx_hash, o) = c.get_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) rlog = r['logs'][0] dec = ABIContractLogDecoder() @@ -78,5 +83,72 @@ class TestVendBase(TestVend): self.assertEqual(int(dec.contents[2], 16), vend_amount) + def test_create_token_nomint_event(self): + self.publish() + 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 = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + rlog = r['logs'][1] + + 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) + + dec = ABIContractLogDecoder() + dec.topic('TokenCreated') + dec.typ(ABIContractType.UINT256) + dec.typ(ABIContractType.UINT256) + dec.typ(ABIContractType.ADDRESS) + dec.apply(rlog['topics'], [rlog['data']]) + self.assertEqual(int(dec.contents[0], 16), 0) + self.assertEqual(int(dec.contents[1], 16), self.initial_supply) + self.assertEqual(int(dec.contents[2], 16), int(vended_token_address, 16)) + + + def test_mint_event(self): + self.publish() + 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) + + nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) + 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) + + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.get_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) + rlog = r['logs'][1] + + dec = ABIContractLogDecoder() + dec.topic('Transfer') + dec.typ(ABIContractType.ADDRESS) + dec.typ(ABIContractType.ADDRESS) + dec.typ(ABIContractType.UINT256) + dec.apply(rlog['topics'], [rlog['data']]) + self.assertEqual(int(dec.contents[0], 16), int(self.vend_address, 16)) + self.assertEqual(int(dec.contents[1], 16), int(self.alice, 16)) + self.assertEqual(int(dec.contents[2], 16), vend_amount) + + if __name__ == '__main__': unittest.main() diff --git a/python/tests/test_lock.py b/python/tests/test_lock.py @@ -1,107 +0,0 @@ -# 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) - 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) - 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/python/tests/test_supply.py b/python/tests/test_supply.py @@ -0,0 +1,81 @@ +# standard imports +import unittest +import logging +import os +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.contract import ABIContractLogDecoder +from chainlib.eth.contract import ABIContractType +from chainlib.eth.tx import receipt +from eth_erc20 import ERC20 +from giftable_erc20_token import GiftableToken +from hexathon import same as same_hex + +# local imports +from erc20_vend.unittest.base import TestVendCore +from erc20_vend import Vend + + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class TestVendBase(TestVendCore): + + def test_create_token_event(self): + self.publish() + + 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) + + c = ERC20(self.chain_spec) + o = c.total_supply(vended_token_address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertEqual(int(r, 16), self.initial_supply) + + + def test_create_token_nomint_event(self): + self.publish(mint=True) + + 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) + + c = ERC20(self.chain_spec) + o = c.total_supply(vended_token_address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertEqual(int(r, 16), 0) + + 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) + + nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) + 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) + + c = Vend(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.get_for(self.vend_address, self.alice, vended_token_address) + self.rpc.do(o) + + c = ERC20(self.chain_spec) + o = c.total_supply(vended_token_address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertEqual(int(r, 16), vend_amount) + + +if __name__ == '__main__': + unittest.main() diff --git a/solidity/Vend.sol b/solidity/Vend.sol @@ -8,40 +8,71 @@ pragma solidity ^0.8.0; import "GiftableToken.sol"; contract ERC20Vend { + address owner; uint256 constant UINT256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; address controlToken; uint8 controlDecimals; uint8 decimals; + uint256 supply; uint256 decimalDivisor; - bool lock; + mapping ( address => uint256 ) returned; GiftableToken[] vendToken; mapping ( address => mapping ( address => uint256 ) ) used; - event TokenCreated(uint256 indexed _idx, address _token); + mapping(address => bool) writers; - constructor(address _controlToken, uint8 _decimals, bool _lock) { + event TokenCreated(uint256 indexed _idx, uint256 indexed _supply, address _token); + + constructor(address _controlToken, uint8 _decimals, bool _mint) { bool r; bytes memory v; controlToken = _controlToken; decimals = _decimals; - lock = _lock; (r, v) = controlToken.call(abi.encodeWithSignature("decimals()")); require(r, "ERR_TOKEN"); controlDecimals = abi.decode(v, (uint8)); require(controlDecimals >= decimals); + if (!_mint) { + (r, v) = controlToken.call(abi.encodeWithSignature("totalSupply()")); + require(r, "ERR_TOKEN"); + supply = abi.decode(v, (uint256)); + } + decimalDivisor = (10 ** (controlDecimals - _decimals)); if (decimalDivisor == 0) { decimalDivisor = 1; } + owner = msg.sender; + } + + // Implements Writer + function addWriter(address _minter) public returns (bool) { + require(msg.sender == owner); + writers[_minter] = true; + return true; } + // Implements Writer + function deleteWriter(address _minter) public returns (bool) { + require(msg.sender == owner || msg.sender == _minter); + writers[_minter] = false; + return true; + } + + // Implements Writer + function isWriter(address _minter) public view returns(bool) { + return writers[_minter] || _minter == owner; + } + + // Retrieve address of vended token by sequential index. function getTokenByIndex(uint256 _idx) public view returns(address) { return address(vendToken[_idx]); } + // Create a new vended token. function create(string calldata _name, string calldata _symbol) public returns (address) { GiftableToken l_contract; address l_address; @@ -51,11 +82,16 @@ contract ERC20Vend { l_address = address(l_contract); l_idx = vendToken.length; vendToken.push(l_contract); - emit TokenCreated(l_idx, l_address); + + if (supply > 0) { + l_contract.mintTo(address(this), supply); + } + emit TokenCreated(l_idx, supply, l_address); return l_address; } - function mintFor(address _token) public returns (uint256) { + // Receive the vended token for the currently held balance. + function getFor(address _token) public returns (uint256) { GiftableToken l_token; bool r; bytes memory v; @@ -75,27 +111,34 @@ contract ERC20Vend { return 0; } - if (lock) { - (r, v) = controlToken.call(abi.encodeWithSignature("transferFrom(address,address,uint256)", msg.sender, this, l_controlBalance)); - require(r, "ERR_TOKEN"); - r = abi.decode(v, (bool)); - require(r, "ERR_TOKEN_TRANSFER"); - used[msg.sender][address(l_token)] = l_controlBalance; - } else { - used[msg.sender][address(l_token)] = UINT256_MAX; - } + (r, v) = controlToken.call(abi.encodeWithSignature("transferFrom(address,address,uint256)", msg.sender, this, l_controlBalance)); + require(r, "ERR_TOKEN"); + r = abi.decode(v, (bool)); + require(r, "ERR_TOKEN_TRANSFER"); + used[msg.sender][address(l_token)] = l_controlBalance; if (decimalDivisor == 0) { l_ratioedValue = l_controlBalance; } else { l_ratioedValue = l_controlBalance / decimalDivisor; } - if (!l_token.mintTo(msg.sender, l_ratioedValue)) { - revert("ERR_MINT"); + + if (supply == 0) { + if (!l_token.mintTo(msg.sender, l_ratioedValue)) { + revert("ERR_MINT"); + } + } else { + (r, v) = _token.call(abi.encodeWithSignature("transfer(address,uint256)", msg.sender, l_ratioedValue)); + require(r, "ERR_TOKEN"); + r = abi.decode(v, (bool)); + require(r, "ERR_VEND_TOKEN_TRANSFER"); } return l_ratioedValue; } + // If contract locks exchanged tokens, this can be called to retrieve the locked tokens. + // The vended token balance MUST match the original balance emitted on the exchange. + // The caller must have given allowance for the full amount. function withdrawFor(address _token) public returns (uint256) { bool r; bytes memory v; @@ -110,13 +153,16 @@ contract ERC20Vend { 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"); + if (l_vendBalance == UINT256_MAX) { + return 0; } + (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"); + returned[_token] += l_vendBalance; + (r, v) = controlToken.call(abi.encodeWithSignature("transfer(address,uint256)", msg.sender, l_balance)); require(r, "ERR_TOKEN"); r = abi.decode(v, (bool)); @@ -125,22 +171,46 @@ contract ERC20Vend { return l_balance; } + // burn used vend tokens. + // should self-destruct contract if possible when supply reaches 0. + function burnFor(address _token) public returns(uint256) { + bool r; + bytes memory v; + uint256 l_burnValue; + + l_burnValue = returned[_token]; + (r, v) = _token.call(abi.encodeWithSignature("burn(uint256)", l_burnValue)); + require(r, "ERR_TOKEN"); + r = abi.decode(v, (bool)); + require(r, "ERR_TOKEN_BURN"); + returned[_token] = 0; + return l_burnValue; + } + // returns UINT256_MAX if lock is inactive - // reverts if locked and target does not have the original balance + // reverts if target does not have the original balance function checkLock(address _token, address _target) private returns (uint256) { bool r; bytes memory v; uint256 l_currentBalance; uint256 l_heldBalance; - if (lock) { - (r, v) = _token.call(abi.encodeWithSignature("balanceOf(address)", _target)); - require(r, "ERR_TOKEN"); - l_currentBalance = abi.decode(v, (uint256)); - l_heldBalance = used[_target][_token]; - require(l_currentBalance * decimalDivisor == l_heldBalance, "ERR_LOCKED"); - return l_currentBalance; + (r, v) = _token.call(abi.encodeWithSignature("balanceOf(address)", _target)); + require(r, "ERR_TOKEN"); + l_currentBalance = abi.decode(v, (uint256)); + l_heldBalance = used[_target][_token]; + require(l_currentBalance * decimalDivisor == l_heldBalance, "ERR_LOCKED"); + return l_currentBalance; + } + + // Implements EIP165 + function supportsInterface(bytes4 _sum) public pure returns (bool) { + if (_sum == 0x01ffc9a7) { // EIP165 + return true; + } + if (_sum == 0xabe1f1f5) { // Writer + return true; } - return UINT256_MAX; + return false; } }