erc20-demurrage-token

ERC20 token with redistributed continual demurrage
Log | Files | Refs | README

commit ae2c1b41240487ed47674a32276240451c9c31fa
parent ffc041c1a3618e7f58836ca21a3015a4f0b23dd0
Author: lash <dev@holbrook.no>
Date:   Thu,  9 Feb 2023 06:49:18 +0000

Rewrite base unittest module, reinstate more contract methods

Diffstat:
Mpython/erc20_demurrage_token/data/DemurrageTokenSingleNocap.bin | 4++--
Mpython/erc20_demurrage_token/data/DemurrageTokenSingleNocap.json | 2+-
Mpython/erc20_demurrage_token/unittest/__init__.py | 2+-
Apython/erc20_demurrage_token/unittest/newbase.py | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/requirements.txt | 4++--
Msolidity/DemurrageTokenSingleNocap.sol | 433+++++++++++++++++++++++++++++++++++++++----------------------------------------
6 files changed, 352 insertions(+), 227 deletions(-)

diff --git a/python/erc20_demurrage_token/data/DemurrageTokenSingleNocap.bin b/python/erc20_demurrage_token/data/DemurrageTokenSingleNocap.bin @@ -1 +1 @@ -61010060405264e8d4a510006a52b7d2dcc80cd2e40000006200002391906200043b565b6080908152503480156200003657600080fd5b506040516200448a3803806200448a83398181016040528101906200005c91906200073a565b62000066620003c1565b33600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600d6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550866006908162000132919062000a5b565b50856007908162000144919062000a5b565b508460ff166008819055504260038190555060035460a08181525050603c836200016f91906200043b565b60c0818152505060646a52b7d2dcc80cd2e400000062000190919062000b42565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550836fffffffffffffffffffffffffffffffff1660e08181525050620002326000600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16600060016200033d640100000000026401000000009004565b90506000819080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548168ffffffffffffffffff021916908368ffffffffffffffffff160217905550604082015181600001600d6101000a8154816cffffffffffffffffffffffffff02191690836cffffffffffffffffffffffffff160217905550505081600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050505062000b88565b62000347620003c1565b62000351620003c1565b82816000019063ffffffff16908163ffffffff168152505083816020019068ffffffffffffffffff16908168ffffffffffffffffff16815250508481604001906cffffffffffffffffffffffffff1690816cffffffffffffffffffffffffff168152505080915050949350505050565b6040518060600160405280600063ffffffff168152602001600068ffffffffffffffffff16815260200160006cffffffffffffffffffffffffff1681525090565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620004488262000402565b9150620004558362000402565b9250828202620004658162000402565b915082820484148315176200047f576200047e6200040c565b5b5092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620004ef82620004a4565b810181811067ffffffffffffffff82111715620005115762000510620004b5565b5b80604052505050565b60006200052662000486565b9050620005348282620004e4565b919050565b600067ffffffffffffffff821115620005575762000556620004b5565b5b6200056282620004a4565b9050602081019050919050565b60005b838110156200058f57808201518184015260208101905062000572565b60008484015250505050565b6000620005b2620005ac8462000539565b6200051a565b905082815260208101848484011115620005d157620005d06200049f565b5b620005de8482856200056f565b509392505050565b600082601f830112620005fe57620005fd6200049a565b5b8151620006108482602086016200059b565b91505092915050565b600060ff82169050919050565b620006318162000619565b81146200063d57600080fd5b50565b600081519050620006518162000626565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b6200067e8162000657565b81146200068a57600080fd5b50565b6000815190506200069e8162000673565b92915050565b620006af8162000402565b8114620006bb57600080fd5b50565b600081519050620006cf81620006a4565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200070282620006d5565b9050919050565b6200071481620006f5565b81146200072057600080fd5b50565b600081519050620007348162000709565b92915050565b60008060008060008060c087890312156200075a576200075962000490565b5b600087015167ffffffffffffffff8111156200077b576200077a62000495565b5b6200078989828a01620005e6565b965050602087015167ffffffffffffffff811115620007ad57620007ac62000495565b5b620007bb89828a01620005e6565b9550506040620007ce89828a0162000640565b9450506060620007e189828a016200068d565b9350506080620007f489828a01620006be565b92505060a06200080789828a0162000723565b9150509295509295509295565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200086757607f821691505b6020821081036200087d576200087c6200081f565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620008ea7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620008a8565b620008f68683620008a8565b95508019841693508086168417925050509392505050565b6000819050919050565b600062000939620009336200092d8462000402565b6200090e565b62000402565b9050919050565b6000819050919050565b620009558362000918565b6200096d620009648262000940565b848454620008b8565b825550505050565b600090565b6200098462000975565b620009918184846200094a565b505050565b5b81811015620009b957620009ad6000826200097a565b60018101905062000997565b5050565b601f82111562000a0857620009d28162000883565b620009dd8462000898565b81016020851015620009ed578190505b62000a05620009fc8562000898565b83018262000996565b50505b505050565b60008160020a8304905092915050565b600062000a306000198460080262000a0d565b1980831691505092915050565b600062000a4b838362000a1d565b9150826002028217905092915050565b62000a668262000814565b67ffffffffffffffff81111562000a825762000a81620004b5565b5b62000a8e82546200084e565b62000a9b828285620009bd565b600060209050601f83116001811462000ad3576000841562000abe578287015190505b62000aca858262000a3d565b86555062000b3a565b601f19841662000ae38662000883565b60005b8281101562000b0d5784890151825560018201915060208501945060208101905062000ae6565b8683101562000b2d578489015162000b29601f89168262000a1d565b8355505b6001600288020188555050505b505050505050565b600062000b4f8262000657565b915062000b5c8362000657565b925082820262000b6c8162000657565b915080821462000b815762000b806200040c565b5b5092915050565b60805160a05160c05160e05161388962000c0160003960008181610eb9015261119c01526000818161170001528181611dbe0152818161236b015261250801526000818161172c01528181612529015261256e0152600081816118060152818161183e015281816118b6015261234701526138896000f3fe608060405234801561001057600080fd5b50600436106102d8576000357c010000000000000000000000000000000000000000000000000000000090048063731f237c1161019f578063a9059cbb11610106578063d397de60116100bf578063eda4e6d611610099578063eda4e6d6146109bf578063f2fde38b146109dd578063f83da35d14610a0d578063f84e521314610a3d576102d8565b8063d397de6014610953578063d89135cd14610983578063e8095295146109a1576102d8565b8063a9059cbb14610869578063ab28cea014610899578063b470aade146108b7578063c0ab7077146108d5578063c7a7f89a14610905578063d340ef8a14610935576102d8565b80638f0b2d5d116101585780638f0b2d5d146107815780638f1df6bc1461079d578063936d9e7a146107bb57806395d89b41146107eb578063983b2d5614610809578063a457c2d714610839576102d8565b8063731f237c146106cd57806373f42561146106eb57806374bedb951461070957806379ba50971461072757806384dde4af146107455780638da5cb5b14610763576102d8565b806340452d911161024357806351b4541c116101fc57806351b4541c146105bf57806358b2833b146105ef5780636721d4ef1461060d5780636787a9be1461063d5780636a2d094e1461066d57806370a082311461069d576102d8565b806340452d91146104b157806342966c68146104e3578063449a52f8146104ff57806347a505171461052f5780634abfbba21461055f5780634d0df4fd1461058f576102d8565b8063229ba19711610295578063229ba197146103b557806323b872dd146103d35780633092afd5146104035780633133348714610433578063313ce567146104635780633950935114610481576102d8565b806301ffc9a7146102dd57806306fdde031461030d578063095ea7b31461032b57806309f28f3c1461035b57806318160ddd146103795780631989c6a814610397575b600080fd5b6102f760048036038101906102f29190612d7b565b610a6d565b6040516103049190612dc3565b60405180910390f35b610315610c13565b6040516103229190612e6e565b60405180910390f35b61034560048036038101906103409190612f24565b610ca1565b6040516103529190612dc3565b60405180910390f35b610363610e72565b6040516103709190612f8f565b60405180910390f35b610381610e94565b60405161038e9190612fb9565b60405180910390f35b61039f610eab565b6040516103ac9190612fb9565b60405180910390f35b6103bd610eb7565b6040516103ca9190612fb9565b60405180910390f35b6103ed60048036038101906103e89190612fd4565b610edb565b6040516103fa9190612dc3565b60405180910390f35b61041d60048036038101906104189190613027565b61108e565b60405161042a9190612dc3565b60405180910390f35b61044d60048036038101906104489190613054565b611181565b60405161045a9190612fb9565b60405180910390f35b61046b611235565b6040516104789190612fb9565b60405180910390f35b61049b60048036038101906104969190612f24565b61123b565b6040516104a89190612dc3565b60405180910390f35b6104cb60048036038101906104c69190613094565b6113d1565b6040516104da9392919061312c565b60405180910390f35b6104fd60048036038101906104f89190613094565b611445565b005b61051960048036038101906105149190612f24565b611573565b6040516105269190612dc3565b60405180910390f35b61054960048036038101906105449190613027565b6116b3565b6040516105569190612fb9565b60405180910390f35b61057960048036038101906105749190613094565b6116fc565b6040516105869190612fb9565b60405180910390f35b6105a960048036038101906105a491906132cb565b61175c565b6040516105b69190612dc3565b60405180910390f35b6105d960048036038101906105d49190613094565b6117c9565b6040516105e69190612fb9565b60405180910390f35b6105f76117ea565b6040516106049190612fb9565b60405180910390f35b61062760048036038101906106229190613054565b6117f0565b6040516106349190612fb9565b60405180910390f35b61065760048036038101906106529190613094565b611871565b6040516106649190612fb9565b60405180910390f35b61068760048036038101906106829190613094565b6118f1565b6040516106949190612fb9565b60405180910390f35b6106b760048036038101906106b29190613027565b611912565b6040516106c49190612fb9565b60405180910390f35b6106d56119ca565b6040516106e29190612dc3565b60405180910390f35b6106f36119db565b6040516107009190612fb9565b60405180910390f35b6107116119e1565b60405161071e9190612fb9565b60405180910390f35b61072f6119e7565b60405161073c9190612dc3565b60405180910390f35b61074d611b8e565b60405161075a9190613307565b60405180910390f35b61076b611bb4565b6040516107789190613307565b60405180910390f35b61079b60048036038101906107969190613027565b611bda565b005b6107a5611c78565b6040516107b29190612dc3565b60405180910390f35b6107d560048036038101906107d091906132cb565b611f17565b6040516107e29190612fb9565b60405180910390f35b6107f3611f45565b6040516108009190612e6e565b60405180910390f35b610823600480360381019061081e9190613027565b611fd3565b6040516108309190612dc3565b60405180910390f35b610853600480360381019061084e9190612f24565b612090565b6040516108609190612dc3565b60405180910390f35b610883600480360381019061087e9190612f24565b6122af565b6040516108909190612dc3565b60405180910390f35b6108a1612345565b6040516108ae9190612fb9565b60405180910390f35b6108bf612369565b6040516108cc9190612fb9565b60405180910390f35b6108ef60048036038101906108ea9190613094565b61238d565b6040516108fc9190612dc3565b60405180910390f35b61091f600480360381019061091a91906132cb565b6124c5565b60405161092c9190612fb9565b60405180910390f35b61093d6124de565b60405161094a9190612fb9565b60405180910390f35b61096d600480360381019061096891906132cb565b6124e4565b60405161097a9190612fb9565b60405180910390f35b61098b6124f8565b6040516109989190612fb9565b60405180910390f35b6109a9612502565b6040516109b69190612f8f565b60405180910390f35b6109c761256c565b6040516109d49190612fb9565b60405180910390f35b6109f760048036038101906109f29190613027565b612590565b604051610a049190612dc3565b60405180910390f35b610a276004803603810190610a229190613322565b612632565b604051610a3491906133f8565b60405180910390f35b610a576004803603810190610a5291906132cb565b6126b2565b604051610a649190612fb9565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610ac15760019050610c0e565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610b135760019050610c0e565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610b655760019050610c0e565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610bb75760019050610c0e565b6337a47be47c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610c095760019050610c0e565b600090505b919050565b60068054610c2090613442565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4c90613442565b8015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b505050505081565b6000806000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115610d6d5760008314610d6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d63906134bf565b60405180910390fd5b5b610d75611c78565b50610d7f83611871565b905080600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610e5f9190612fb9565b60405180910390a3600191505092915050565b600260009054906101000a90046fffffffffffffffffffffffffffffffff1681565b6000600c54600954610ea6919061350e565b905090565b60008080549050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000610ee8611c78565b50610ef284611871565b915081600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610f7d57600080fd5b81600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611009919061350e565b9250508190555061101b8686846126cf565b90508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8660405161107a9190612fb9565b60405180910390a380925050509392505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061111757503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b61112057600080fd5b6000600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600080600064e8d4a5100091506a52b7d2dcc80cd2e40000007f00000000000000000000000000000000000000000000000000000000000000006111c59190613571565b905060005b8481101561120e5764e8d4a5100082846111e491906135a2565b6111ee9190613571565b836111f9919061350e565b92508080611206906135e4565b9150506111ca565b5064e8d4a51000858361122191906135a2565b61122b9190613571565b9250505092915050565b60085481565b600080611246611c78565b5061125083611871565b905080600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112de919061362c565b925050819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040516113be9190612fb9565b60405180910390a3600191505092915050565b600081815481106113e157600080fd5b906000526020600020016000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a900468ffffffffffffffffff169080600001600d9054906101000a90046cffffffffffffffffffffffffff16905083565b600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661149b57600080fd5b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548111156114e757600080fd5b60006114f282611871565b90506114fc6119ca565b5061150733826126f4565b5081600c600082825461151a919061362c565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040516115679190612fb9565b60405180910390a25050565b600080600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f9906136ac565b60405180910390fd5b61160a611c78565b5061161483611871565b90508260096000828254611628919061362c565b9250508190555061163984826127fb565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8856040516116979190612fb9565b60405180910390a36116a76128bf565b50600191505092915050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60007f00000000000000000000000000000000000000000000000000000000000000008261172a91906135a2565b7f0000000000000000000000000000000000000000000000000000000000000000611755919061362c565b9050919050565b600080826000015163ffffffff16111561177957600090506117c4565b6000826020015168ffffffffffffffffff16111561179a57600090506117c4565b600082604001516cffffffffffffffffffffffffff1611156117bf57600090506117c4565b600190505b919050565b6000603c82426117d9919061350e565b6117e39190613571565b9050919050565b60035481565b6000806402540be4008361180491906135a2565b7f000000000000000000000000000000000000000000000000000000000000000061182f919061350e565b8461183a91906135a2565b90507f0000000000000000000000000000000000000000000000000000000000000000816118689190613571565b91505092915050565b60006402540be400600260009054906101000a90046fffffffffffffffffffffffffffffffff166118a291906136cc565b6fffffffffffffffffffffffffffffffff167f0000000000000000000000000000000000000000000000000000000000000000836118e091906135a2565b6118ea9190613571565b9050919050565b6000603c8242611901919061350e565b61190b9190613571565b9050919050565b600080600080611921856116b3565b925061192e6003546117c9565b905061197a6402540be400600260009054906101000a90046fffffffffffffffffffffffffffffffff1661196291906136cc565b6fffffffffffffffffffffffffffffffff1682611181565b6fffffffffffffffffffffffffffffffff16915064e8d4a510006a52b7d2dcc80cd2e40000006119aa91906135a2565b82846119b691906135a2565b6119c09190613571565b9350505050919050565b60006119d6600061238d565b905090565b600c5481565b600b5481565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a4457600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35090565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c3457600080fd5b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611c82612cd3565b611c8a612cd3565b611c92612cd3565b6000806000806000611ca26119ca565b50611cab612a9c565b9750611cb68861175c565b15611ccc57600098505050505050505050611f14565b6000600a5481548110611ce257611ce1613709565b5b906000526020600020016040518060600160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1668ffffffffffffffffff16815260200160008201600d9054906101000a90046cffffffffffffffffffffffffff166cffffffffffffffffffffffffff166cffffffffffffffffffffffffff16815250509550611d9e886124e4565b9450600185611dad919061362c565b9050611db8866126b2565b9350603c7f0000000000000000000000000000000000000000000000000000000000000000611de79190613571565b9150611df38483611181565b9250611e09600084611e03610e94565b84612632565b96506000879080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548168ffffffffffffffffff021916908368ffffffffffffffffff160217905550604082015181600001600d6101000a8154816cffffffffffffffffffffffffff02191690836cffffffffffffffffffffffffff1602179055505050611ecf87612c41565b507f55d243082e019fce4009ccea5368b92e436c17586a1e793c7deda16df4e5d67581604051611eff9190612fb9565b60405180910390a16001985050505050505050505b90565b6000806000611f25846124c5565b9150611f30846126b2565b9050611f3c82826117f0565b92505050919050565b60078054611f5290613442565b80601f0160208091040260200160405190810160405280929190818152602001828054611f7e90613442565b8015611fcb5780601f10611fa057610100808354040283529160200191611fcb565b820191906000526020600020905b815481529060010190602001808311611fae57829003601f168201915b505050505081565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461202f57600080fd5b6001600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b60008061209c83611871565b905080600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561212757600080fd5b61212f611c78565b5080600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546121bc919061350e565b925050819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460405161229c9190612fb9565b60405180910390a3600191505092915050565b60008060006122bc611c78565b506122c684611871565b91506122d33386846126cf565b90508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040516123329190612fb9565b60405180910390a3809250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080600061239d6003546117c9565b9150600082036123b2576000925050506124c0565b600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1690506000841180156123f457508184105b156123fd578391505b6124078183611181565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550603c8261244c91906135a2565b600354612459919061362c565b60038190555080826003547fa0717e54e02bd9829db5e6e998aec0ae9de796b8d150a3cc46a92ab869697755600260009054906101000a90046fffffffffffffffffffffffffffffffff166040516124b19190613773565b60405180910390a46001925050505b919050565b6000816020015168ffffffffffffffffff169050919050565b600a5481565b6000816000015163ffffffff169050919050565b6000600c54905090565b600060017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000042612553919061350e565b61255d9190613571565b612567919061362c565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125ec57600080fd5b81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550919050565b61263a612cd3565b612642612cd3565b82816000019063ffffffff16908163ffffffff168152505083816020019068ffffffffffffffffff16908168ffffffffffffffffff16815250508481604001906cffffffffffffffffffffffffff1690816cffffffffffffffffffffffffff168152505080915050949350505050565b600081604001516cffffffffffffffffffffffffff169050919050565b6000806126dc85846126f4565b506126e784846127fb565b5060019150509392505050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000850361275057600093505050506127f5565b612759866116b3565b92508483101561279e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612795906137da565b60405180910390fd5b84836127aa919061350e565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000850361285757600093505050506128b9565b612860866116b3565b9250848361286e919061362c565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b60006128c9612cd3565b60006128d3610e94565b9050600060016000805490506128e9919061350e565b815481106128fa576128f9613709565b5b906000526020600020016040518060600160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1668ffffffffffffffffff16815260200160008201600d9054906101000a90046cffffffffffffffffffffffffff166cffffffffffffffffffffffffff166cffffffffffffffffffffffffff1681525050915080826020019068ffffffffffffffffff16908168ffffffffffffffffff168152505081600060016000805490506129e4919061350e565b815481106129f5576129f4613709565b5b9060005260206000200160008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548168ffffffffffffffffff021916908368ffffffffffffffffff160217905550604082015181600001600d6101000a8154816cffffffffffffffffffffffffff02191690836cffffffffffffffffffffffffff16021790555090505060019250505090565b612aa4612cd3565b612aac612cd3565b612ab4612cd3565b600080600a5481548110612acb57612aca613709565b5b906000526020600020016040518060600160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1668ffffffffffffffffff16815260200160008201600d9054906101000a90046cffffffffffffffffffffffffff166cffffffffffffffffffffffffff166cffffffffffffffffffffffffff168152505092503073ffffffffffffffffffffffffffffffffffffffff1663e80952956040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381865afa158015612be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c099190613826565b6fffffffffffffffffffffffffffffffff169050612c26836124e4565b8111612c3757819350505050612c3e565b8293505050505b90565b6000806000612c4f84611f17565b9150600b54612c5d83611871565b612c67919061350e565b9050612c95600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16826127fb565b506001600a6000828254612ca9919061362c565b9250508190555080600b6000828254612cc2919061362c565b925050819055508192505050919050565b6040518060600160405280600063ffffffff168152602001600068ffffffffffffffffff16815260200160006cffffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612d5881612d23565b8114612d6357600080fd5b50565b600081359050612d7581612d4f565b92915050565b600060208284031215612d9157612d90612d1e565b5b6000612d9f84828501612d66565b91505092915050565b60008115159050919050565b612dbd81612da8565b82525050565b6000602082019050612dd86000830184612db4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612e18578082015181840152602081019050612dfd565b60008484015250505050565b6000601f19601f8301169050919050565b6000612e4082612dde565b612e4a8185612de9565b9350612e5a818560208601612dfa565b612e6381612e24565b840191505092915050565b60006020820190508181036000830152612e888184612e35565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ebb82612e90565b9050919050565b612ecb81612eb0565b8114612ed657600080fd5b50565b600081359050612ee881612ec2565b92915050565b6000819050919050565b612f0181612eee565b8114612f0c57600080fd5b50565b600081359050612f1e81612ef8565b92915050565b60008060408385031215612f3b57612f3a612d1e565b5b6000612f4985828601612ed9565b9250506020612f5a85828601612f0f565b9150509250929050565b60006fffffffffffffffffffffffffffffffff82169050919050565b612f8981612f64565b82525050565b6000602082019050612fa46000830184612f80565b92915050565b612fb381612eee565b82525050565b6000602082019050612fce6000830184612faa565b92915050565b600080600060608486031215612fed57612fec612d1e565b5b6000612ffb86828701612ed9565b935050602061300c86828701612ed9565b925050604061301d86828701612f0f565b9150509250925092565b60006020828403121561303d5761303c612d1e565b5b600061304b84828501612ed9565b91505092915050565b6000806040838503121561306b5761306a612d1e565b5b600061307985828601612f0f565b925050602061308a85828601612f0f565b9150509250929050565b6000602082840312156130aa576130a9612d1e565b5b60006130b884828501612f0f565b91505092915050565b600063ffffffff82169050919050565b6130da816130c1565b82525050565b600068ffffffffffffffffff82169050919050565b6130fe816130e0565b82525050565b60006cffffffffffffffffffffffffff82169050919050565b61312681613104565b82525050565b600060608201905061314160008301866130d1565b61314e60208301856130f5565b61315b604083018461311d565b949350505050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6131a082612e24565b810181811067ffffffffffffffff821117156131bf576131be613168565b5b80604052505050565b60006131d2612d14565b90506131de8282613197565b919050565b6131ec816130c1565b81146131f757600080fd5b50565b600081359050613209816131e3565b92915050565b613218816130e0565b811461322357600080fd5b50565b6000813590506132358161320f565b92915050565b61324481613104565b811461324f57600080fd5b50565b6000813590506132618161323b565b92915050565b60006060828403121561327d5761327c613163565b5b61328760606131c8565b90506000613297848285016131fa565b60008301525060206132ab84828501613226565b60208301525060406132bf84828501613252565b60408301525092915050565b6000606082840312156132e1576132e0612d1e565b5b60006132ef84828501613267565b91505092915050565b61330181612eb0565b82525050565b600060208201905061331c60008301846132f8565b92915050565b6000806000806080858703121561333c5761333b612d1e565b5b600061334a87828801612f0f565b945050602061335b87828801612f0f565b935050604061336c87828801612f0f565b925050606061337d87828801612f0f565b91505092959194509250565b613392816130c1565b82525050565b6133a1816130e0565b82525050565b6133b081613104565b82525050565b6060820160008201516133cc6000850182613389565b5060208201516133df6020850182613398565b5060408201516133f260408501826133a7565b50505050565b600060608201905061340d60008301846133b6565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061345a57607f821691505b60208210810361346d5761346c613413565b5b50919050565b7f5a45524f5f464952535400000000000000000000000000000000000000000000600082015250565b60006134a9600a83612de9565b91506134b482613473565b602082019050919050565b600060208201905081810360008301526134d88161349c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061351982612eee565b915061352483612eee565b925082820390508181111561353c5761353b6134df565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061357c82612eee565b915061358783612eee565b92508261359757613596613542565b5b828204905092915050565b60006135ad82612eee565b91506135b883612eee565b92508282026135c681612eee565b915082820484148315176135dd576135dc6134df565b5b5092915050565b60006135ef82612eee565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613621576136206134df565b5b600182019050919050565b600061363782612eee565b915061364283612eee565b925082820190508082111561365a576136596134df565b5b92915050565b7f4552525f41434345535300000000000000000000000000000000000000000000600082015250565b6000613696600a83612de9565b91506136a182613660565b602082019050919050565b600060208201905081810360008301526136c581613689565b9050919050565b60006136d782612f64565b91506136e283612f64565b92508282026136f081612f64565b9150808214613702576137016134df565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000819050919050565b600061375d61375861375384612f64565b613738565b612eee565b9050919050565b61376d81613742565b82525050565b60006020820190506137886000830184613764565b92915050565b7f4552525f4f5645525350454e4400000000000000000000000000000000000000600082015250565b60006137c4600d83612de9565b91506137cf8261378e565b602082019050919050565b600060208201905081810360008301526137f3816137b7565b9050919050565b61380381612f64565b811461380e57600080fd5b50565b600081519050613820816137fa565b92915050565b60006020828403121561383c5761383b612d1e565b5b600061384a84828501613811565b9150509291505056fea264697066735822122008caebcd04cc1bb42095504e6580d634464818fdc889058130c22a47ada837f064736f6c63430008110033 -\ No newline at end of file +60c06040523480156200001157600080fd5b5060405162004360380380620043608339818101604052810190620000379190620008f7565b6801000000000000000083600f0b126200005057600080fd5b6200005a6200060f565b33600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600e6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550866006908162000126919062000c18565b50856007908162000138919062000c18565b508460ff166008819055504260038190555060035460808181525050603c8362000163919062000d2e565b60a081815250506200018a60016200035064010000000002620016b0176401000000009004565b600260006101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff160217905550620001e4846200037764010000000002620016d6176401000000009004565b600d60006101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff160217905550620002556000600260009054906101000a9004600f0b64ffffffffff1660006001620003cb640100000000026401000000009004565b90506000819080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548168ffffffffffffffffff021916908368ffffffffffffffffff160217905550604082015181600001600d6101000a81548164ffffffffff021916908364ffffffffff160217905550505081601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050505062000d79565b6000677fffffffffffffff8211156200036857600080fd5b6040829060020a029050919050565b60008082600f0b136200038957600080fd5b60806fb17217f7d1cf79abc9e3b39803f2f6af620003b6846200043f640100000000026401000000009004565b600f0b02908060020a82049150509050919050565b620003d56200060f565b620003df6200060f565b82816000019063ffffffff16908163ffffffff168152505083816020019068ffffffffffffffffff16908168ffffffffffffffffff168152505084816040019064ffffffffff16908164ffffffffff168152505080915050949350505050565b60008082600f0b136200045157600080fd5b60008083600f0b90506801000000000000000081126200048d576040819060008212600003808260020a82851804189250505090506040820191505b6401000000008112620004bc576020819060008212600003808260020a82851804189250505090506020820191505b620100008112620004e9576010819060008212600003808260020a82851804189250505090506010820191505b610100811262000515576008819060008212600003808260020a82851804189250505090506008820191505b6010811262000540576004819060008212600003808260020a82851804189250505090506004820191505b600481126200056b576002819060008212600003808260020a82851804189250505090506002820191505b600281126200057b576001820191505b600060408084039060020a029050600083607f0386600f0b9060020a029050600067800000000000000090505b600081131562000602578182029150600060ff83908060020a8204915050905080607f0183908060020a8204915050925080820284019350506001819060008212600003808260020a8285180418925050509050620005a8565b5081945050505050919050565b6040518060600160405280600063ffffffff168152602001600068ffffffffffffffffff168152602001600064ffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620006b18262000666565b810181811067ffffffffffffffff82111715620006d357620006d262000677565b5b80604052505050565b6000620006e862000648565b9050620006f68282620006a6565b919050565b600067ffffffffffffffff82111562000719576200071862000677565b5b620007248262000666565b9050602081019050919050565b60005b838110156200075157808201518184015260208101905062000734565b60008484015250505050565b6000620007746200076e84620006fb565b620006dc565b90508281526020810184848401111562000793576200079262000661565b5b620007a084828562000731565b509392505050565b600082601f830112620007c057620007bf6200065c565b5b8151620007d28482602086016200075d565b91505092915050565b600060ff82169050919050565b620007f381620007db565b8114620007ff57600080fd5b50565b6000815190506200081381620007e8565b92915050565b600081600f0b9050919050565b620008318162000819565b81146200083d57600080fd5b50565b600081519050620008518162000826565b92915050565b6000819050919050565b6200086c8162000857565b81146200087857600080fd5b50565b6000815190506200088c8162000861565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620008bf8262000892565b9050919050565b620008d181620008b2565b8114620008dd57600080fd5b50565b600081519050620008f181620008c6565b92915050565b60008060008060008060c0878903121562000917576200091662000652565b5b600087015167ffffffffffffffff81111562000938576200093762000657565b5b6200094689828a01620007a8565b965050602087015167ffffffffffffffff8111156200096a576200096962000657565b5b6200097889828a01620007a8565b95505060406200098b89828a0162000802565b94505060606200099e89828a0162000840565b9350506080620009b189828a016200087b565b92505060a0620009c489828a01620008e0565b9150509295509295509295565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000a2457607f821691505b60208210810362000a3a5762000a39620009dc565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b60006008830262000aa77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000a65565b62000ab3868362000a65565b95508019841693508086168417925050509392505050565b6000819050919050565b600062000af662000af062000aea8462000857565b62000acb565b62000857565b9050919050565b6000819050919050565b62000b128362000ad5565b62000b2a62000b218262000afd565b84845462000a75565b825550505050565b600090565b62000b4162000b32565b62000b4e81848462000b07565b505050565b5b8181101562000b765762000b6a60008262000b37565b60018101905062000b54565b5050565b601f82111562000bc55762000b8f8162000a40565b62000b9a8462000a55565b8101602085101562000baa578190505b62000bc262000bb98562000a55565b83018262000b53565b50505b505050565b60008160020a8304905092915050565b600062000bed6000198460080262000bca565b1980831691505092915050565b600062000c08838362000bda565b9150826002028217905092915050565b62000c2382620009d1565b67ffffffffffffffff81111562000c3f5762000c3e62000677565b5b62000c4b825462000a0b565b62000c5882828562000b7a565b600060209050601f83116001811462000c90576000841562000c7b578287015190505b62000c87858262000bfa565b86555062000cf7565b601f19841662000ca08662000a40565b60005b8281101562000cca5784890151825560018201915060208501945060208101905062000ca3565b8683101562000cea578489015162000ce6601f89168262000bda565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000d3b8262000857565b915062000d488362000857565b925082820262000d588162000857565b9150828204841483151762000d725762000d7162000cff565b5b5092915050565b60805160a0516135a562000dbb60003960008181610f15015281816114c50152611516015260008181610f4101528181611537015261157c01526135a56000f3fe608060405234801561001057600080fd5b506004361061024f576000357c01000000000000000000000000000000000000000000000000000000009004806370a082311161014d57806395d89b41116100d5578063d89135cd11610099578063d89135cd14610750578063e80952951461076e578063eda4e6d61461078c578063f2fde38b146107aa578063f83da35d146107da5761024f565b806395d89b4114610696578063983b2d56146106b4578063b470aade146106e4578063d340ef8a14610702578063d4792037146107205761024f565b806384dde4af1161011c57806384dde4af146105de5780638b8ff2d6146105fc5780638da5cb5b1461062c5780638f0b2d5d1461064a57806394c8a69a146106665761024f565b806370a082311461055457806373f425611461058457806374bedb95146105a257806379ba5097146105c05761024f565b8063313ce567116101db5780634abfbba21161019f5780634abfbba21461047657806351b4541c146104a657806358b2833b146104d65780636787a9be146104f45780636a2d094e146105245761024f565b8063313ce567146103aa57806340452d91146103c857806342966c68146103fa578063449a52f81461041657806347a50517146104465761024f565b806318160ddd1161022257806318160ddd146102f05780631989c6a81461030e578063229ba1971461032c5780633092afd51461034a578063313334871461037a5761024f565b806301ffc9a71461025457806306fdde031461028457806309f28f3c146102a257806310a10f37146102c0575b600080fd5b61026e60048036038101906102699190612c5b565b61080a565b60405161027b9190612ca3565b60405180910390f35b61028c6109b0565b6040516102999190612d4e565b60405180910390f35b6102aa610a3e565b6040516102b79190612d8c565b60405180910390f35b6102da60048036038101906102d59190612f45565b610a51565b6040516102e79190612f8b565b60405180910390f35b6102f8610a65565b6040516103059190612f8b565b60405180910390f35b610316610a7c565b6040516103239190612f8b565b60405180910390f35b610334610a88565b6040516103419190612d8c565b60405180910390f35b610364600480360381019061035f9190613004565b610a9b565b6040516103719190612ca3565b60405180910390f35b610394600480360381019061038f919061305d565b610b8e565b6040516103a19190612f8b565b60405180910390f35b6103b2610bfa565b6040516103bf9190612f8b565b60405180910390f35b6103e260048036038101906103dd919061309d565b610c00565b6040516103f1939291906130f7565b60405180910390f35b610414600480360381019061040f919061309d565b610c6c565b005b610430600480360381019061042b919061312e565b610d91565b60405161043d9190612ca3565b60405180910390f35b610460600480360381019061045b9190613004565b610ec8565b60405161046d9190612f8b565b60405180910390f35b610490600480360381019061048b919061309d565b610f11565b60405161049d9190612f8b565b60405180910390f35b6104c060048036038101906104bb919061309d565b610f71565b6040516104cd9190612f8b565b60405180910390f35b6104de610f92565b6040516104eb9190612f8b565b60405180910390f35b61050e6004803603810190610509919061309d565b610f98565b60405161051b9190612f8b565b60405180910390f35b61053e6004803603810190610539919061309d565b610fd9565b60405161054b9190612f8b565b60405180910390f35b61056e60048036038101906105699190613004565b610ffa565b60405161057b9190612f8b565b60405180910390f35b61058c611061565b6040516105999190612f8b565b60405180910390f35b6105aa611067565b6040516105b79190612f8b565b60405180910390f35b6105c861106d565b6040516105d59190612ca3565b60405180910390f35b6105e6611214565b6040516105f3919061317d565b60405180910390f35b61061660048036038101906106119190612f45565b61123a565b6040516106239190612f8b565b60405180910390f35b61063461124f565b604051610641919061317d565b60405180910390f35b610664600480360381019061065f9190613004565b611275565b005b610680600480360381019061067b9190612f45565b611313565b60405161068d9190612ca3565b60405180910390f35b61069e611378565b6040516106ab9190612d4e565b60405180910390f35b6106ce60048036038101906106c99190613004565b611406565b6040516106db9190612ca3565b60405180910390f35b6106ec6114c3565b6040516106f99190612f8b565b60405180910390f35b61070a6114e7565b6040516107179190612f8b565b60405180910390f35b61073a60048036038101906107359190612f45565b6114ed565b6040516107479190612f8b565b60405180910390f35b610758611506565b6040516107659190612f8b565b60405180910390f35b610776611510565b60405161078391906131c3565b60405180910390f35b61079461157a565b6040516107a19190612f8b565b60405180910390f35b6107c460048036038101906107bf9190613004565b61159e565b6040516107d19190612ca3565b60405180910390f35b6107f460048036038101906107ef91906131de565b611640565b60405161080191906132b4565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361085e57600190506109ab565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036108b057600190506109ab565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361090257600190506109ab565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361095457600190506109ab565b6337a47be47c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036109a657600190506109ab565b600090505b919050565b600680546109bd906132fe565b80601f01602080910402602001604051908101604052809291908181526020018280546109e9906132fe565b8015610a365780601f10610a0b57610100808354040283529160200191610a36565b820191906000526020600020905b815481529060010190602001808311610a1957829003601f168201915b505050505081565b600260009054906101000a9004600f0b81565b6000816000015163ffffffff169050919050565b6000600c54600954610a77919061335e565b905090565b60008080549050905090565b600d60009054906101000a9004600f0b81565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610b2457503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b610b2d57600080fd5b6000600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600080600080610b9d866116b0565b9250610ba8856116b0565b9150610bc3600d60009054906101000a9004600f0b83611718565b9050610bce81611797565b9050610bda8382611718565b9050610be581611824565b67ffffffffffffffff16935050505092915050565b60085481565b60008181548110610c1057600080fd5b906000526020600020016000915090508060000160009054906101000a900463ffffffff16908060000160049054906101000a900468ffffffffffffffffff169080600001600d9054906101000a900464ffffffffff16905083565b600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610cc257600080fd5b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054811115610d0e57600080fd5b6000610d1982610f98565b9050610d253382611859565b5081600c6000828254610d389190613392565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca583604051610d859190612f8b565b60405180910390a25050565b600080600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610e20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1790613412565b60405180910390fd5b610e2983610f98565b90508260096000828254610e3d9190613392565b92505081905550610e4e8482611960565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f885604051610eac9190612f8b565b60405180910390a3610ebc611a24565b50600191505092915050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60007f000000000000000000000000000000000000000000000000000000000000000082610f3f9190613432565b7f0000000000000000000000000000000000000000000000000000000000000000610f6a9190613392565b9050919050565b6000603c8242610f81919061335e565b610f8b91906134a3565b9050919050565b60035481565b600080610fbc600260009054906101000a9004600f0b610fb7856116b0565b611718565b9050610fc781611824565b67ffffffffffffffff16915050919050565b6000603c8242610fe9919061335e565b610ff391906134a3565b9050919050565b60008060008061101161100c86610ec8565b6116b0565b925061101e600354610f71565b905061103983600260009054906101000a9004600f0b611718565b915061105761104783611824565b67ffffffffffffffff1682610b8e565b9350505050919050565b600c5481565b600b5481565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110ca57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35090565b601060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000816040015164ffffffffff169050919050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112cf57600080fd5b80601060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080826000015163ffffffff1611156113305760009050611373565b6000826020015168ffffffffffffffffff1611156113515760009050611373565b6000826040015164ffffffffff16111561136e5760009050611373565b600190505b919050565b60078054611385906132fe565b80601f01602080910402602001604051908101604052809291908181526020018280546113b1906132fe565b80156113fe5780601f106113d3576101008083540402835291602001916113fe565b820191906000526020600020905b8154815290600101906020018083116113e157829003601f168201915b505050505081565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461146257600080fd5b6001600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600a5481565b6000816020015168ffffffffffffffffff169050919050565b6000600c54905090565b600060017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000042611561919061335e565b61156b91906134a3565b6115759190613392565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115fa57600080fd5b81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550919050565b611648612bbb565b611650612bbb565b82816000019063ffffffff16908163ffffffff168152505083816020019068ffffffffffffffffff16908168ffffffffffffffffff168152505084816040019064ffffffffff16908164ffffffffff168152505080915050949350505050565b6000677fffffffffffffff8211156116c757600080fd5b6040829060020a029050919050565b60008082600f0b136116e757600080fd5b60806fb17217f7d1cf79abc9e3b39803f2f6af61170384611bd9565b600f0b02908060020a82049150509050919050565b600080604083600f0b85600f0b029060008212600003808260020a82851804189250505090507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b811215801561178457506f7fffffffffffffffffffffffffffffff600f0b8113155b61178d57600080fd5b8091505092915050565b60006840000000000000000082600f0b126117b157600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000082600f0b12156117e5576000905061181f565b61181c6080700171547652b82fe1777d0ffda0d23a7d1284600f0b029060008212600003808260020a828518041892505050611d9f565b90505b919050565b60008082600f0b121561183657600080fd5b604082600f0b9060008212600003808260020a8285180418925050509050919050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600085036118b5576000935050505061195a565b6118be86610ec8565b925084831015611903576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fa90613520565b60405180910390fd5b848361190f919061335e565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600085036119bc5760009350505050611a1e565b6119c586610ec8565b925084836119d39190613392565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b6000611a2e612bbb565b6000611a38610a65565b905060006001600080549050611a4e919061335e565b81548110611a5f57611a5e613540565b5b906000526020600020016040518060600160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1668ffffffffffffffffff16815260200160008201600d9054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681525050915080826020019068ffffffffffffffffff16908168ffffffffffffffffff16815250508160006001600080549050611b31919061335e565b81548110611b4257611b41613540565b5b9060005260206000200160008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548168ffffffffffffffffff021916908368ffffffffffffffffff160217905550604082015181600001600d6101000a81548164ffffffffff021916908364ffffffffff16021790555090505060019250505090565b60008082600f0b13611bea57600080fd5b60008083600f0b9050680100000000000000008112611c25576040819060008212600003808260020a82851804189250505090506040820191505b6401000000008112611c53576020819060008212600003808260020a82851804189250505090506020820191505b620100008112611c7f576010819060008212600003808260020a82851804189250505090506010820191505b6101008112611caa576008819060008212600003808260020a82851804189250505090506008820191505b60108112611cd4576004819060008212600003808260020a82851804189250505090506004820191505b60048112611cfe576002819060008212600003808260020a82851804189250505090506002820191505b60028112611d0d576001820191505b600060408084039060020a029050600083607f0386600f0b9060020a029050600067800000000000000090505b6000811315611d92578182029150600060ff83908060020a8204915050905080607f0183908060020a8204915050925080820284019350506001819060008212600003808260020a8285180418925050509050611d3a565b5081945050505050919050565b60006840000000000000000082600f0b12611db957600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000082600f0b1215611ded5760009050612bb6565b60006f80000000000000000000000000000000905060006780000000000000008416600f0b1315611e3b57608070016a09e667f3bcc908b2fb1366ea957d3e8202908060020a820491505090505b60006740000000000000008416600f0b1315611e745760807001306fe0a31b7152de8d5a46305c85edec8202908060020a820491505090505b60006720000000000000008416600f0b1315611ead5760807001172b83c7d517adcdf7c8c50eb14a791f8202908060020a820491505090505b60006710000000000000008416600f0b1315611ee657608070010b5586cf9890f6298b92b71842a983638202908060020a820491505090505b60006708000000000000008416600f0b1315611f1f5760807001059b0d31585743ae7c548eb68ca417fd8202908060020a820491505090505b60006704000000000000008416600f0b1315611f58576080700102c9a3e778060ee6f7caca4f7a29bde88202908060020a820491505090505b60006702000000000000008416600f0b1315611f9157608070010163da9fb33356d84a66ae336dcdfa3f8202908060020a820491505090505b60006701000000000000008416600f0b1315611fca576080700100b1afa5abcbed6129ab13ec11dc95438202908060020a820491505090505b600066800000000000008416600f0b131561200257608070010058c86da1c09ea1ff19d294cf2f679b8202908060020a820491505090505b600066400000000000008416600f0b131561203a5760807001002c605e2e8cec506d21bfc89a23a00f8202908060020a820491505090505b600066200000000000008416600f0b1315612072576080700100162f3904051fa128bca9c55c31e5df8202908060020a820491505090505b600066100000000000008416600f0b13156120aa5760807001000b175effdc76ba38e31671ca9397258202908060020a820491505090505b600066080000000000008416600f0b13156120e2576080700100058ba01fb9f96d6cacd4b180917c3d8202908060020a820491505090505b600066040000000000008416600f0b131561211a57608070010002c5cc37da9491d0985c348c68e7b38202908060020a820491505090505b600066020000000000008416600f0b13156121525760807001000162e525ee054754457d59952920268202908060020a820491505090505b600066010000000000008416600f0b131561218a57608070010000b17255775c040618bf4a4ade83fc8202908060020a820491505090505b6000658000000000008416600f0b13156121c15760807001000058b91b5bc9ae2eed81e9b7d4cfab8202908060020a820491505090505b6000654000000000008416600f0b13156121f8576080700100002c5c89d5ec6ca4d7c8acc017b7c98202908060020a820491505090505b6000652000000000008416600f0b131561222f57608070010000162e43f4f831060e02d839a9d16d8202908060020a820491505090505b6000651000000000008416600f0b1315612266576080700100000b1721bcfc99d9f890ea069117638202908060020a820491505090505b6000650800000000008416600f0b131561229d57608070010000058b90cf1e6d97f9ca14dbcc16288202908060020a820491505090505b6000650400000000008416600f0b13156122d45760807001000002c5c863b73f016468f6bac5ca2b8202908060020a820491505090505b6000650200000000008416600f0b131561230b576080700100000162e430e5a18f6119e3c02282a58202908060020a820491505090505b6000650100000000008416600f0b13156123425760807001000000b1721835514b86e6d96efd1bfe8202908060020a820491505090505b60006480000000008416600f0b1315612378576080700100000058b90c0b48c6be5df846c5b2ef8202908060020a820491505090505b60006440000000008416600f0b13156123ae57608070010000002c5c8601cc6b9e94213c72737a8202908060020a820491505090505b60006420000000008416600f0b13156123e45760807001000000162e42fff037df38aa2b219f068202908060020a820491505090505b60006410000000008416600f0b131561241a57608070010000000b17217fba9c739aa5819f44f98202908060020a820491505090505b60006408000000008416600f0b13156124505760807001000000058b90bfcdee5acd3c1cedc8238202908060020a820491505090505b60006404000000008416600f0b1315612486576080700100000002c5c85fe31f35a6a30da1be508202908060020a820491505090505b60006402000000008416600f0b13156124bc57608070010000000162e42ff0999ce3541b9fffcf8202908060020a820491505090505b60006401000000008416600f0b13156124f2576080700100000000b17217f80f4ef5aadda455548202908060020a820491505090505b600063800000008416600f0b131561252757608070010000000058b90bfbf8479bd5a81b51ad8202908060020a820491505090505b600063400000008416600f0b131561255c5760807001000000002c5c85fdf84bd62ae30a74cc8202908060020a820491505090505b600063200000008416600f0b1315612591576080700100000000162e42fefb2fed257559bdaa8202908060020a820491505090505b600063100000008416600f0b13156125c65760807001000000000b17217f7d5a7716bba4a9ae8202908060020a820491505090505b600063080000008416600f0b13156125fb576080700100000000058b90bfbe9ddbac5e109cce8202908060020a820491505090505b600063040000008416600f0b131561263057608070010000000002c5c85fdf4b15de6f17eb0d8202908060020a820491505090505b600063020000008416600f0b13156126655760807001000000000162e42fefa494f1478fde058202908060020a820491505090505b600063010000008416600f0b131561269a57608070010000000000b17217f7d20cf927c8e94c8202908060020a820491505090505b6000628000008416600f0b13156126ce5760807001000000000058b90bfbe8f71cb4e4b33d8202908060020a820491505090505b6000624000008416600f0b1315612702576080700100000000002c5c85fdf477b662b269458202908060020a820491505090505b6000622000008416600f0b131561273657608070010000000000162e42fefa3ae53369388c8202908060020a820491505090505b6000621000008416600f0b131561276a576080700100000000000b17217f7d1d351a389d408202908060020a820491505090505b6000620800008416600f0b131561279e57608070010000000000058b90bfbe8e8b2d3d4ede8202908060020a820491505090505b6000620400008416600f0b13156127d25760807001000000000002c5c85fdf4741bea6e77e8202908060020a820491505090505b6000620200008416600f0b1315612806576080700100000000000162e42fefa39fe95583c28202908060020a820491505090505b6000620100008416600f0b131561283a5760807001000000000000b17217f7d1cfb72b45e18202908060020a820491505090505b60006180008416600f0b131561286d576080700100000000000058b90bfbe8e7cc35c3f08202908060020a820491505090505b60006140008416600f0b13156128a057608070010000000000002c5c85fdf473e242ea388202908060020a820491505090505b60006120008416600f0b13156128d35760807001000000000000162e42fefa39f02b772c8202908060020a820491505090505b60006110008416600f0b131561290657608070010000000000000b17217f7d1cf7d83c1a8202908060020a820491505090505b60006108008416600f0b13156129395760807001000000000000058b90bfbe8e7bdcbe2e8202908060020a820491505090505b60006104008416600f0b131561296c576080700100000000000002c5c85fdf473dea871f8202908060020a820491505090505b60006102008416600f0b131561299f57608070010000000000000162e42fefa39ef44d918202908060020a820491505090505b60006101008416600f0b13156129d2576080700100000000000000b17217f7d1cf79e9498202908060020a820491505090505b600060808416600f0b1315612a0457608070010000000000000058b90bfbe8e7bce5448202908060020a820491505090505b600060408416600f0b1315612a365760807001000000000000002c5c85fdf473de6eca8202908060020a820491505090505b600060208416600f0b1315612a68576080700100000000000000162e42fefa39ef366f8202908060020a820491505090505b600060108416600f0b1315612a9a5760807001000000000000000b17217f7d1cf79afa8202908060020a820491505090505b600060088416600f0b1315612acc576080700100000000000000058b90bfbe8e7bcd6d8202908060020a820491505090505b600060048416600f0b1315612afe57608070010000000000000002c5c85fdf473de6b28202908060020a820491505090505b600060028416600f0b1315612b305760807001000000000000000162e42fefa39ef3588202908060020a820491505090505b600060018416600f0b1315612b6257608070010000000000000000b17217f7d1cf79ab8202908060020a820491505090505b604083600f0b9060008212600003808260020a828518041892505050603f03600f0b81908060020a820491505090506f7fffffffffffffffffffffffffffffff600f0b811115612bb157600080fd5b809150505b919050565b6040518060600160405280600063ffffffff168152602001600068ffffffffffffffffff168152602001600064ffffffffff1681525090565b6000604051905090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612c3881612c03565b8114612c4357600080fd5b50565b600081359050612c5581612c2f565b92915050565b600060208284031215612c7157612c70612bfe565b5b6000612c7f84828501612c46565b91505092915050565b60008115159050919050565b612c9d81612c88565b82525050565b6000602082019050612cb86000830184612c94565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612cf8578082015181840152602081019050612cdd565b60008484015250505050565b6000601f19601f8301169050919050565b6000612d2082612cbe565b612d2a8185612cc9565b9350612d3a818560208601612cda565b612d4381612d04565b840191505092915050565b60006020820190508181036000830152612d688184612d15565b905092915050565b600081600f0b9050919050565b612d8681612d70565b82525050565b6000602082019050612da16000830184612d7d565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612de482612d04565b810181811067ffffffffffffffff82111715612e0357612e02612dac565b5b80604052505050565b6000612e16612bf4565b9050612e228282612ddb565b919050565b600063ffffffff82169050919050565b612e4081612e27565b8114612e4b57600080fd5b50565b600081359050612e5d81612e37565b92915050565b600068ffffffffffffffffff82169050919050565b612e8181612e63565b8114612e8c57600080fd5b50565b600081359050612e9e81612e78565b92915050565b600064ffffffffff82169050919050565b612ebe81612ea4565b8114612ec957600080fd5b50565b600081359050612edb81612eb5565b92915050565b600060608284031215612ef757612ef6612da7565b5b612f016060612e0c565b90506000612f1184828501612e4e565b6000830152506020612f2584828501612e8f565b6020830152506040612f3984828501612ecc565b60408301525092915050565b600060608284031215612f5b57612f5a612bfe565b5b6000612f6984828501612ee1565b91505092915050565b6000819050919050565b612f8581612f72565b82525050565b6000602082019050612fa06000830184612f7c565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612fd182612fa6565b9050919050565b612fe181612fc6565b8114612fec57600080fd5b50565b600081359050612ffe81612fd8565b92915050565b60006020828403121561301a57613019612bfe565b5b600061302884828501612fef565b91505092915050565b61303a81612f72565b811461304557600080fd5b50565b60008135905061305781613031565b92915050565b6000806040838503121561307457613073612bfe565b5b600061308285828601613048565b925050602061309385828601613048565b9150509250929050565b6000602082840312156130b3576130b2612bfe565b5b60006130c184828501613048565b91505092915050565b6130d381612e27565b82525050565b6130e281612e63565b82525050565b6130f181612ea4565b82525050565b600060608201905061310c60008301866130ca565b61311960208301856130d9565b61312660408301846130e8565b949350505050565b6000806040838503121561314557613144612bfe565b5b600061315385828601612fef565b925050602061316485828601613048565b9150509250929050565b61317781612fc6565b82525050565b6000602082019050613192600083018461316e565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b6131bd81613198565b82525050565b60006020820190506131d860008301846131b4565b92915050565b600080600080608085870312156131f8576131f7612bfe565b5b600061320687828801613048565b945050602061321787828801613048565b935050604061322887828801613048565b925050606061323987828801613048565b91505092959194509250565b61324e81612e27565b82525050565b61325d81612e63565b82525050565b61326c81612ea4565b82525050565b6060820160008201516132886000850182613245565b50602082015161329b6020850182613254565b5060408201516132ae6040850182613263565b50505050565b60006060820190506132c96000830184613272565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061331657607f821691505b602082108103613329576133286132cf565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061336982612f72565b915061337483612f72565b925082820390508181111561338c5761338b61332f565b5b92915050565b600061339d82612f72565b91506133a883612f72565b92508282019050808211156133c0576133bf61332f565b5b92915050565b7f4552525f41434345535300000000000000000000000000000000000000000000600082015250565b60006133fc600a83612cc9565b9150613407826133c6565b602082019050919050565b6000602082019050818103600083015261342b816133ef565b9050919050565b600061343d82612f72565b915061344883612f72565b925082820261345681612f72565b9150828204841483151761346d5761346c61332f565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006134ae82612f72565b91506134b983612f72565b9250826134c9576134c8613474565b5b828204905092915050565b7f4552525f4f5645525350454e4400000000000000000000000000000000000000600082015250565b600061350a600d83612cc9565b9150613515826134d4565b602082019050919050565b60006020820190508181036000830152613539816134fd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212204b75a1346dc9b6fd8022d4b7843ef48d6a1dcba4ee1022ef5799e0df78620e2364736f6c63430008110033 +\ No newline at end of file diff --git a/python/erc20_demurrage_token/data/DemurrageTokenSingleNocap.json b/python/erc20_demurrage_token/data/DemurrageTokenSingleNocap.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"uint128","name":"_taxLevelMinute","type":"uint128"},{"internalType":"uint256","name":"_periodMinutes","type":"uint256"},{"internalType":"address","name":"_defaultSinkAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_burner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_foo","type":"bytes32"}],"name":"Debug","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_periodCount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newAmount","type":"uint256"}],"name":"Decayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"},{"indexed":true,"internalType":"address","name":"_beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_period","type":"uint256"}],"name":"Period","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Redistribution","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"actualPeriod","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"addMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"applyDemurrage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rounds","type":"uint256"}],"name":"applyDemurrageLimited","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"baseBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"changePeriod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"decayBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"demurrageAmount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_target","type":"uint256"}],"name":"demurrageCycles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"demurrageTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"},{"internalType":"uint256","name":"_demurrageAmount","type":"uint256"}],"name":"getDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint104","name":"demurrage","type":"uint104"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"getDistributionFromRedistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastTimestamp","type":"uint256"}],"name":"getMinutesDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_periodCount","type":"uint256"}],"name":"getPeriodTimeDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint104","name":"demurrage","type":"uint104"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"isEmptyRedistribution","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"lastPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redistributionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redistributions","outputs":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint104","name":"demurrage","type":"uint104"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"removeMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolutionFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sinkAddress","type":"address"}],"name":"setSinkAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"toBaseAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_participants","type":"uint256"},{"internalType":"uint256","name":"_demurrageModifierPpm","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"toRedistribution","outputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint104","name":"demurrage","type":"uint104"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint104","name":"demurrage","type":"uint104"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"toRedistributionDemurrageModifier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint104","name":"demurrage","type":"uint104"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"toRedistributionPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint104","name":"demurrage","type":"uint104"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"toRedistributionSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSink","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"int128","name":"_taxLevel","type":"int128"},{"internalType":"uint256","name":"_periodMinutes","type":"uint256"},{"internalType":"address","name":"_defaultSinkAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_burner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_foo","type":"bytes32"}],"name":"Debug","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_periodCount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newAmount","type":"uint256"}],"name":"Decayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"},{"indexed":true,"internalType":"address","name":"_beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_period","type":"uint256"}],"name":"Period","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Redistribution","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"actualPeriod","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"addMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"baseBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"decayBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"demurrageAmount","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_target","type":"uint256"}],"name":"demurrageCycles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"demurrageTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastTimestamp","type":"uint256"}],"name":"getMinutesDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_periodCount","type":"uint256"}],"name":"getPeriodTimeDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint40","name":"demurrage","type":"uint40"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"isEmptyRedistribution","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"lastPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redistributionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redistributions","outputs":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint40","name":"demurrage","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"removeMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sinkAddress","type":"address"}],"name":"setSinkAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxLevel","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"toBaseAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_participants","type":"uint256"},{"internalType":"uint256","name":"_demurrageModifierPpm","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"toRedistribution","outputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint40","name":"demurrage","type":"uint40"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint40","name":"demurrage","type":"uint40"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"toRedistributionDemurrageModifier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint40","name":"demurrage","type":"uint40"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"toRedistributionPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint72","name":"value","type":"uint72"},{"internalType":"uint40","name":"demurrage","type":"uint40"}],"internalType":"struct DemurrageTokenSingleCap.redistributionItem","name":"_redistribution","type":"tuple"}],"name":"toRedistributionSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSink","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/python/erc20_demurrage_token/unittest/__init__.py b/python/erc20_demurrage_token/unittest/__init__.py @@ -1 +1 @@ -from .base import * +from .newbase import * diff --git a/python/erc20_demurrage_token/unittest/newbase.py b/python/erc20_demurrage_token/unittest/newbase.py @@ -0,0 +1,134 @@ +# standard imports +import logging +import os + +# external imports +from chainlib.eth.unittest.ethtester import EthTesterCase +from chainlib.eth.tx import ( + receipt, + ) +from chainlib.eth.block import ( + block_latest, + block_by_number, + ) +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.constant import ZERO_ADDRESS + +# local imports +from erc20_demurrage_token import ( + DemurrageTokenSettings, + DemurrageToken, + ) + +logg = logging.getLogger() + +#BLOCKTIME = 5 # seconds +TAX_LEVEL = int(10000 * 2) # 2% +# calc "1-(0.98)^(1/518400)" <- 518400 = 30 days of blocks +# 0.00000003897127107225 +#PERIOD = int(60/BLOCKTIME) * 60 * 24 * 30 # month +PERIOD = 10 + + +class TestTokenDeploy: + + """tax level is ppm, 1000000 = 100%""" + def __init__(self, rpc, token_symbol='FOO', token_name='Foo Token', sink_address=ZERO_ADDRESS, supply=10**12, tax_level=TAX_LEVEL, period=PERIOD): + self.tax_level = tax_level + self.period_seconds = period * 60 + + self.settings = DemurrageTokenSettings() + self.settings.name = token_name + self.settings.symbol = token_symbol + self.settings.decimals = 6 + self.settings.demurrage_level = tax_level ** (1 / period) + self.settings.period_minutes = period + self.settings.sink_address = sink_address + self.sink_address = self.settings.sink_address + logg.debug('using demurrage token settings: {}'.format(self.settings)) + + o = block_latest() + self.start_block = rpc.do(o) + + o = block_by_number(self.start_block, include_tx=False) + r = rpc.do(o) + + try: + self.start_time = int(r['timestamp'], 16) + except TypeError: + self.start_time = int(r['timestamp']) + + self.default_supply = supply + #self.default_supply_cap = int(self.default_supply * 10) + self.default_supply_cap = 0 + + + def deploy(self, rpc, deployer_address, interface, mode, supply_cap=0): + tx_hash = None + o = None + (tx_hash, o) = interface.constructor(deployer_address, self.settings, redistribute=False, cap=0) + + r = rpc.do(o) + o = receipt(tx_hash) + r = rpc.do(o) + assert r['status'] == 1 + self.start_block = r['block_number'] + self.address = r['contract_address'] + + o = block_by_number(r['block_number']) + r = rpc.do(o) + self.start_time = r['timestamp'] + + return self.address + + +class TestDemurrage(EthTesterCase): + + def setUp(self): + super(TestDemurrage, self).setUp() + period = PERIOD + try: + period = getattr(self, 'period') + except AttributeError as e: + pass + self.deployer = TestTokenDeploy(self.rpc, period=period) + self.default_supply = self.deployer.default_supply + self.default_supply_cap = self.deployer.default_supply_cap + self.start_block = None + self.address = None + self.start_time = None + + + def deploy(self, interface): + self.address = self.deployer.deploy(self.rpc, self.accounts[0], interface, mode, supply_cap=self.default_supply_cap) + self.start_block = self.deployer.start_block + self.start_time = self.deployer.start_time + self.tax_level = self.deployer.tax_level + self.period_seconds = self.deployer.period_seconds + self.sink_address = self.deployer.sink_address + + logg.debug('contract address {} start block {} start time {}'.format(self.address, self.start_block, self.start_time)) + + + def assert_within_lower(self, v, target, tolerance_ppm): + lower_target = target - (target * (tolerance_ppm / 1000000)) + self.assertGreaterEqual(v, lower_target) + self.assertLessEqual(v, target) + logg.debug('asserted within lower {} <= {} <= {}'.format(lower_target, v, target)) + + + def tearDown(self): + pass + + +class TestDemurrageDefault(TestDemurrage): + + def setUp(self): + super(TestDemurrageDefault, self).setUp() + + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + + self.deploy(c) + + logg.info('deployed with mode {}'.format(self.mode)) diff --git a/python/requirements.txt b/python/requirements.txt @@ -1,3 +1,3 @@ -chainlib-eth>=0.1.0,<0.2.0 -eth-erc20~=0.3.0 +chainlib-eth~=0.4.11 +eth-erc20~=0.5.0 funga-eth~=0.6.0 diff --git a/solidity/DemurrageTokenSingleNocap.sol b/solidity/DemurrageTokenSingleNocap.sol @@ -138,96 +138,97 @@ contract DemurrageTokenSingleCap { } -// // Change sink address for redistribution -// function setSinkAddress(address _sinkAddress) public { -// require(msg.sender == owner); -// sinkAddress = _sinkAddress; -// } -// -// // Given address will be allowed to call the mintTo() function -// function addMinter(address _minter) public returns (bool) { -// require(msg.sender == owner); -// minter[_minter] = true; -// return true; -// } -// -// // Given address will no longer be allowed to call the mintTo() function -// function removeMinter(address _minter) public returns (bool) { -// require(msg.sender == owner || _minter == msg.sender); -// minter[_minter] = false; -// return true; -// } -// -// /// Implements ERC20 -// function balanceOf(address _account) public view returns (uint256) { -// uint256 baseBalance; -// uint256 currentDemurragedAmount; -// uint256 periodCount; -// -// baseBalance = baseBalanceOf(_account); -// -// periodCount = getMinutesDelta(demurrageTimestamp); -// -// currentDemurragedAmount = uint128(decayBy(demurrageAmount * 10000000000, periodCount)); -// -// return (baseBalance * currentDemurragedAmount) / (nanoDivider * 1000000000000); -// } -// -// /// Balance unmodified by demurrage -// function baseBalanceOf(address _account) public view returns (uint256) { -// return account[_account]; -// } -// -// /// Increases base balance for a single account -// function increaseBaseBalance(address _account, uint256 _delta) private returns (bool) { -// uint256 oldBalance; -// uint256 newBalance; -// uint256 workAccount; -// -// workAccount = uint256(account[_account]); -// -// if (_delta == 0) { -// return false; -// } -// -// oldBalance = baseBalanceOf(_account); -// account[_account] = oldBalance + _delta; -// return true; -// } -// -// /// Decreases base balance for a single account -// function decreaseBaseBalance(address _account, uint256 _delta) private returns (bool) { -// uint256 oldBalance; -// uint256 newBalance; -// uint256 workAccount; -// -// workAccount = uint256(account[_account]); -// -// if (_delta == 0) { -// return false; -// } -// -// oldBalance = baseBalanceOf(_account); -// require(oldBalance >= _delta, 'ERR_OVERSPEND'); // overspend guard -// account[_account] = oldBalance - _delta; -// return true; -// } -// -// // Creates new tokens out of thin air, and allocates them to the given address -// // Triggers tax -// function mintTo(address _beneficiary, uint256 _amount) external returns (bool) { -// uint256 baseAmount; -// -// require(minter[msg.sender], 'ERR_ACCESS'); -// -// changePeriod(); -// baseAmount = toBaseAmount(_amount); -// supply += _amount; -// increaseBaseBalance(_beneficiary, baseAmount); -// emit Mint(msg.sender, _beneficiary, _amount); -// saveRedistributionSupply(); -// return true; -// } + // Change sink address for redistribution + function setSinkAddress(address _sinkAddress) public { + require(msg.sender == owner); + sinkAddress = _sinkAddress; + } + + // Given address will be allowed to call the mintTo() function + function addMinter(address _minter) public returns (bool) { + require(msg.sender == owner); + minter[_minter] = true; + return true; + } + + // Given address will no longer be allowed to call the mintTo() function + function removeMinter(address _minter) public returns (bool) { + require(msg.sender == owner || _minter == msg.sender); + minter[_minter] = false; + return true; + } + + /// Implements ERC20 + function balanceOf(address _account) public view returns (uint256) { + int128 baseBalance; + int128 currentDemurragedAmount; + uint256 periodCount; + + baseBalance = ABDKMath64x64.fromUInt(baseBalanceOf(_account)); + + periodCount = getMinutesDelta(demurrageTimestamp); + + currentDemurragedAmount = ABDKMath64x64.mul(baseBalance, demurrageAmount); + return decayBy(ABDKMath64x64.toUInt(currentDemurragedAmount), periodCount); + + //return (baseBalance * currentDemurragedAmount) / (nanoDivider * 1000000000000); + } + + // Balance unmodified by demurrage + function baseBalanceOf(address _account) public view returns (uint256) { + return account[_account]; + } + + /// Increases base balance for a single account + function increaseBaseBalance(address _account, uint256 _delta) private returns (bool) { + uint256 oldBalance; + uint256 newBalance; + uint256 workAccount; + + workAccount = uint256(account[_account]); + + if (_delta == 0) { + return false; + } + + oldBalance = baseBalanceOf(_account); + account[_account] = oldBalance + _delta; + return true; + } + + /// Decreases base balance for a single account + function decreaseBaseBalance(address _account, uint256 _delta) private returns (bool) { + uint256 oldBalance; + uint256 newBalance; + uint256 workAccount; + + workAccount = uint256(account[_account]); + + if (_delta == 0) { + return false; + } + + oldBalance = baseBalanceOf(_account); + require(oldBalance >= _delta, 'ERR_OVERSPEND'); // overspend guard + account[_account] = oldBalance - _delta; + return true; + } + + // Creates new tokens out of thin air, and allocates them to the given address + // Triggers tax + function mintTo(address _beneficiary, uint256 _amount) external returns (bool) { + uint256 baseAmount; + + require(minter[msg.sender], 'ERR_ACCESS'); + + //changePeriod(); + baseAmount = toBaseAmount(_amount); + supply += _amount; + increaseBaseBalance(_beneficiary, baseAmount); + emit Mint(msg.sender, _beneficiary, _amount); + saveRedistributionSupply(); + return true; + } // Deserializes the redistribution word function toRedistribution(uint256 _participants, uint256 _demurrageModifierPpm, uint256 _value, uint256 _period) public pure returns(redistributionItem memory) { @@ -239,46 +240,46 @@ contract DemurrageTokenSingleCap { return redistribution; } -// -// // Serializes the demurrage period part of the redistribution word -// function toRedistributionPeriod(redistributionItem memory _redistribution) public pure returns (uint256) { -// return uint256(_redistribution.period); -// } -// -// // Serializes the supply part of the redistribution word -// function toRedistributionSupply(redistributionItem memory _redistribution) public pure returns (uint256) { -// return uint256(_redistribution.value); -// } -// -// // Serializes the number of participants part of the redistribution word -// function toRedistributionDemurrageModifier(redistributionItem memory _redistribution) public pure returns (uint256) { -// return uint256(_redistribution.demurrage); -// } -// -// -// // Client accessor to the redistributions array length -// function redistributionCount() public view returns (uint256) { -// return redistributions.length; -// } -// -// // Save the current total supply amount to the current redistribution period -// function saveRedistributionSupply() private returns (bool) { -// redistributionItem memory currentRedistribution; -// uint256 grownSupply; -// -// grownSupply = totalSupply(); -// currentRedistribution = redistributions[redistributions.length-1]; -// currentRedistribution.value = uint72(grownSupply); -// -// redistributions[redistributions.length-1] = currentRedistribution; -// return true; -// } -// -// // Get the demurrage period of the current block number -// function actualPeriod() public view returns (uint128) { -// return uint128((block.timestamp - periodStart) / periodDuration + 1); -// } -// + + // Serializes the demurrage period part of the redistribution word + function toRedistributionPeriod(redistributionItem memory _redistribution) public pure returns (uint256) { + return uint256(_redistribution.period); + } + + // Serializes the supply part of the redistribution word + function toRedistributionSupply(redistributionItem memory _redistribution) public pure returns (uint256) { + return uint256(_redistribution.value); + } + + // Serializes the number of participants part of the redistribution word + function toRedistributionDemurrageModifier(redistributionItem memory _redistribution) public pure returns (uint256) { + return uint256(_redistribution.demurrage); + } + + + // Client accessor to the redistributions array length + function redistributionCount() public view returns (uint256) { + return redistributions.length; + } + + // Save the current total supply amount to the current redistribution period + function saveRedistributionSupply() private returns (bool) { + redistributionItem memory currentRedistribution; + uint256 grownSupply; + + grownSupply = totalSupply(); + currentRedistribution = redistributions[redistributions.length-1]; + currentRedistribution.value = uint72(grownSupply); + + redistributions[redistributions.length-1] = currentRedistribution; + return true; + } + + // Get the demurrage period of the current block number + function actualPeriod() public view returns (uint128) { + return uint128((block.timestamp - periodStart) / periodDuration + 1); + } + // // Retrieve next redistribution if the period threshold has been crossed // function checkPeriod() private view returns (redistributionItem memory) { // redistributionItem memory lastRedistribution; @@ -292,14 +293,14 @@ contract DemurrageTokenSingleCap { // } // return lastRedistribution; // } -// + // function getDistribution(uint256 _supply, uint256 _demurrageAmount) public view returns (uint256) { // uint256 difference; // // difference = _supply * (resolutionFactor - (_demurrageAmount * 10000000000)); // return difference / resolutionFactor; // } -// + // function getDistributionFromRedistribution(redistributionItem memory _redistribution) public returns (uint256) { // uint256 redistributionSupply; // uint256 redistributionDemurrage; @@ -321,12 +322,12 @@ contract DemurrageTokenSingleCap { // totalSink += baseUnit; // return unit; // } -// -// // Calculate the time delta in whole minutes passed between given timestamp and current timestamp -// function getMinutesDelta(uint256 _lastTimestamp) public view returns (uint256) { -// return (block.timestamp - _lastTimestamp) / 60; -// } -// + + // Calculate the time delta in whole minutes passed between given timestamp and current timestamp + function getMinutesDelta(uint256 _lastTimestamp) public view returns (uint256) { + return (block.timestamp - _lastTimestamp) / 60; + } + // // Calculate and cache the demurrage value corresponding to the (period of the) time of the method call // function applyDemurrage() public returns (bool) { // return applyDemurrageLimited(0); @@ -354,30 +355,30 @@ contract DemurrageTokenSingleCap { // emit Decayed(demurrageTimestamp, periodCount, lastDemurrageAmount, demurrageAmount); // return true; // } -// -// // Return timestamp of start of period threshold -// function getPeriodTimeDelta(uint256 _periodCount) public view returns (uint256) { -// return periodStart + (_periodCount * periodDuration); -// } -// -// // Amount of demurrage cycles inbetween the current timestamp and the given target time -// function demurrageCycles(uint256 _target) public view returns (uint256) { -// return (block.timestamp - _target) / 60; -// } -// -// function isEmptyRedistribution(redistributionItem memory _redistribution) public pure returns(bool) { -// if (_redistribution.period > 0) { -// return false; -// } -// if (_redistribution.value > 0) { -// return false; -// } -// if (_redistribution.demurrage > 0) { -// return false; -// } -// return true; -// } -// + + // Return timestamp of start of period threshold + function getPeriodTimeDelta(uint256 _periodCount) public view returns (uint256) { + return periodStart + (_periodCount * periodDuration); + } + + // Amount of demurrage cycles inbetween the current timestamp and the given target time + function demurrageCycles(uint256 _target) public view returns (uint256) { + return (block.timestamp - _target) / 60; + } + + function isEmptyRedistribution(redistributionItem memory _redistribution) public pure returns(bool) { + if (_redistribution.period > 0) { + return false; + } + if (_redistribution.value > 0) { + return false; + } + if (_redistribution.demurrage > 0) { + return false; + } + return true; + } + // // Recalculate the demurrage modifier for the new period // // Note that the supply for the consecutive period will be taken at the time of code execution, and thus not necessarily at the time when the redistribution period threshold was crossed. // function changePeriod() public returns (bool) { @@ -425,21 +426,8 @@ contract DemurrageTokenSingleCap { //// } //// return (valueFactor * _value) / growthResolutionFactor; //// } -// -// // Calculate a value reduced by demurrage by the given period -// function decayBy(uint256 _value, uint256 _period) public view returns (uint256) { -// uint256 valueFactor; -// uint256 truncatedTaxLevel; -// -// valueFactor = growthResolutionFactor; -// truncatedTaxLevel = taxLevel / nanoDivider; -// -// for (uint256 i = 0; i < _period; i++) { -// valueFactor = valueFactor - ((valueFactor * truncatedTaxLevel) / growthResolutionFactor); -// } -// return (valueFactor * _value) / growthResolutionFactor; -// } + // Calculate a value reduced by demurrage by the given period function decayBy(uint256 _value, uint256 _period) public view returns (uint256) { int128 valuePoint; int128 periodPoint; @@ -456,11 +444,14 @@ contract DemurrageTokenSingleCap { return ABDKMath64x64.toUInt(v); } -// -// // Inflates the given amount according to the current demurrage modifier -// function toBaseAmount(uint256 _value) public view returns (uint256) { -// return (_value * resolutionFactor) / (demurrageAmount * 10000000000); -// } + + // Inflates the given amount according to the current demurrage modifier + function toBaseAmount(uint256 _value) public view returns (uint256) { + int128 r; + //return (_value * resolutionFactor) / (demurrageAmount * 10000000000); + r = ABDKMath64x64.mul(demurrageAmount, ABDKMath64x64.fromUInt(_value)); + return ABDKMath64x64.toUInt(r); + } // // // Implements ERC20, triggers tax and/or redistribution // function approve(address _spender, uint256 _value) public returns (bool) { @@ -544,46 +535,46 @@ contract DemurrageTokenSingleCap { // // return true; // } -// -// // Implements EIP173 -// function transferOwnership(address _newOwner) public returns (bool) { -// require(msg.sender == owner); -// newOwner = _newOwner; -// } -// -// // Implements OwnedAccepter -// function acceptOwnership() public returns (bool) { -// address oldOwner; -// -// require(msg.sender == newOwner); -// oldOwner = owner; -// owner = newOwner; -// newOwner = address(0); -// emit OwnershipTransferred(oldOwner, owner); -// } -// -// // Explicitly and irretrievably burn tokens -// // Only token minters can burn tokens -// function burn(uint256 _value) public { -// require(minter[msg.sender]); -// require(_value <= account[msg.sender]); -// uint256 _delta = toBaseAmount(_value); -// -// applyDemurrage(); -// decreaseBaseBalance(msg.sender, _delta); -// burned += _value; -// emit Burn(msg.sender, _value); -// } -// -// // Implements ERC20 -// function totalSupply() public view returns (uint256) { -// return supply - burned; -// } -// -// // Return total number of burned tokens -// function totalBurned() public view returns (uint256) { -// return burned; -// } + + // Implements EIP173 + function transferOwnership(address _newOwner) public returns (bool) { + require(msg.sender == owner); + newOwner = _newOwner; + } + + // Implements OwnedAccepter + function acceptOwnership() public returns (bool) { + address oldOwner; + + require(msg.sender == newOwner); + oldOwner = owner; + owner = newOwner; + newOwner = address(0); + emit OwnershipTransferred(oldOwner, owner); + } + + // Explicitly and irretrievably burn tokens + // Only token minters can burn tokens + function burn(uint256 _value) public { + require(minter[msg.sender]); + require(_value <= account[msg.sender]); + uint256 _delta = toBaseAmount(_value); + + //applyDemurrage(); + decreaseBaseBalance(msg.sender, _delta); + burned += _value; + emit Burn(msg.sender, _value); + } + + // Implements ERC20 + function totalSupply() public view returns (uint256) { + return supply - burned; + } + + // Return total number of burned tokens + function totalBurned() public view returns (uint256) { + return burned; + } // Implements EIP165 function supportsInterface(bytes4 _sum) public pure returns (bool) {