erc20-demurrage-token

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

commit 9f27f9e26a0c01990cd46396c378521eddb61c92
parent b4dfb5a3818f31d8e5e35bf5f9293e9969fd1615
Author: nolash <dev@holbrook.no>
Date:   Fri,  4 Jun 2021 09:05:08 +0200

Rename module, add test base and two basic tests to chainlib

Diffstat:
Apython/erc20_demurrage_token/__init__.py | 4++++
Apython/erc20_demurrage_token/data/DemurrageTokenMultiNocap.bin | 2++
Rpython/sarafu_token/data/RedistributedDemurrageToken.json -> python/erc20_demurrage_token/data/DemurrageTokenMultiNocap.json | 0
Rpython/sarafu_token/data/__init__.py -> python/erc20_demurrage_token/data/__init__.py | 0
Apython/erc20_demurrage_token/runnable/deploy.py | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apython/erc20_demurrage_token/token.py | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/requirements.txt | 4++--
Dpython/sarafu_token/__init__.py | 1-
Dpython/sarafu_token/data/RedistributedDemurrageToken.bin | 2--
Dpython/sarafu_token/runnable/deploy.py | 135-------------------------------------------------------------------------------
Dpython/sarafu_token/runnable/legacy/deploy.py | 133-------------------------------------------------------------------------------
Dpython/sarafu_token/token.py | 87-------------------------------------------------------------------------------
Mpython/setup.cfg | 21++++++++++-----------
Mpython/test_requirements.txt | 2+-
Apython/tests/base.py | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/tests/test_basic.py | 329++++++++++++++++++++++++++++++++++++-------------------------------------------
Rsolidity/RedistributedDemurrageToken.sol -> solidity/DemurrageTokenMultiNocap.sol | 0
Msolidity/Makefile | 8++++----
18 files changed, 512 insertions(+), 557 deletions(-)

diff --git a/python/erc20_demurrage_token/__init__.py b/python/erc20_demurrage_token/__init__.py @@ -0,0 +1,4 @@ +from .token import ( + DemurrageToken, + DemurrageTokenSettings, + ) diff --git a/python/erc20_demurrage_token/data/DemurrageTokenMultiNocap.bin b/python/erc20_demurrage_token/data/DemurrageTokenMultiNocap.bin @@ -0,0 +1 @@ +60e06040523480156200001157600080fd5b5060405162003d0238038062003d0283398181016040528101906200003791906200048e565b33600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600a6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555085600590805190602001906200010a92919062000327565b5084600690805190602001906200012392919062000327565b508360ff166007819055504260808181525050603c826200014591906200074d565b60a08181525050620f42406d04ee2d6d415b85acef81000000006200016b91906200074d565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506001600260106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508260c0818152505060006200020a6000620f4240600060016200029b640100000000026401000000009004565b9050600081908060018154018082558091505060019003906000526020600020016000909190919091505581600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460ff16600a62000288919062000610565b6009819055505050505050505062000994565b60008073fffff00000000000000000000000000000000000608c60ff16869060020a021660010281179050710fffffffff00000000000000000000000000606860ff16879060020a0216600102811790506cffffffffffffffffff00000000602060ff16859060020a02166001028117905063ffffffff83166001028117905080915050949350505050565b82805462000335906200082f565b90600052602060002090601f016020900481019282620003595760008555620003a5565b82601f106200037457805160ff1916838001178555620003a5565b82800160010185558215620003a5579182015b82811115620003a457825182559160200191906001019062000387565b5b509050620003b49190620003b8565b5090565b5b80821115620003d3576000816000905550600101620003b9565b5090565b6000620003ee620003e8846200057f565b62000556565b9050828152602081018484840111156200040757600080fd5b62000414848285620007f9565b509392505050565b6000815190506200042d8162000946565b92915050565b600082601f8301126200044557600080fd5b815162000457848260208601620003d7565b91505092915050565b600081519050620004718162000960565b92915050565b60008151905062000488816200097a565b92915050565b60008060008060008060c08789031215620004a857600080fd5b600087015167ffffffffffffffff811115620004c357600080fd5b620004d189828a0162000433565b965050602087015167ffffffffffffffff811115620004ef57600080fd5b620004fd89828a0162000433565b95505060406200051089828a0162000477565b94505060606200052389828a0162000460565b93505060806200053689828a0162000460565b92505060a06200054989828a016200041c565b9150509295509295509295565b60006200056262000575565b905062000570828262000865565b919050565b6000604051905090565b600067ffffffffffffffff8211156200059d576200059c620008f9565b5b620005a88262000928565b9050602081019050919050565b6000808291508390505b60018511156200060757808604811115620005df57620005de6200089b565b5b6001851615620005ef5780820291505b8081029050620005ff8562000939565b9450620005bf565b94509492505050565b60006200061d82620007e2565b91506200062a83620007e2565b9250620006597fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000661565b905092915050565b60008262000673576001905062000746565b8162000683576000905062000746565b81600181146200069c5760028114620006a757620006dd565b600191505062000746565b60ff841115620006bc57620006bb6200089b565b5b8360020a915084821115620006d657620006d56200089b565b5b5062000746565b5060208310610133831016604e8410600b8410161715620007175782820a9050838111156200071157620007106200089b565b5b62000746565b620007268484846001620005b5565b9250905081840481111562000740576200073f6200089b565b5b81810290505b9392505050565b60006200075a82620007e2565b91506200076783620007e2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615620007a357620007a26200089b565b5b828202905092915050565b6000620007bb82620007c2565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101562000819578082015181840152602081019050620007fc565b8381111562000829576000848401525b50505050565b600060028204905060018216806200084857607f821691505b602082108114156200085f576200085e620008ca565b5b50919050565b620008708262000928565b810181811067ffffffffffffffff82111715620008925762000891620008f9565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6000600282049050919050565b6200095181620007ae565b81146200095d57600080fd5b50565b6200096b81620007e2565b81146200097757600080fd5b50565b6200098581620007ec565b81146200099157600080fd5b50565b60805160a05160c0516132ff62000a0360003960008181610ca801528181610f030152818161109401528181611da401528181612426015261245e01526000818161137701528181611d520152611e3f0152600081816113a301528181611e600152611ea501526132ff6000f3fe608060405234801561001057600080fd5b506004361061025a576000357c0100000000000000000000000000000000000000000000000000000000900480636787a9be11610158578063983b2d56116100d5578063e3ab207a11610099578063e3ab207a146107c3578063e54d63f7146107f3578063e809529514610823578063eda4e6d614610841578063f2fde38b1461085f5761025a565b8063983b2d56146106f75780639da7d8ba14610727578063a2119e2f14610757578063a9059cbb14610775578063b470aade146107a55761025a565b8063731f237c1161011c578063731f237c1461066157806379ba50971461067f5780638da5cb5b1461069d5780638f1df6bc146106bb57806395d89b41146106d95761025a565b80636787a9be146105715780636a2d094e146105a15780636d5055a6146105d15780636ffa8a051461060157806370a08231146106315761025a565b80633092afd5116101e657806340fc89f5116101aa57806340fc89f514610493578063449a52f8146104c357806347a50517146104f35780634abfbba214610523578063573cc507146105535761025a565b80633092afd5146103b557806331333487146103e5578063313ce5671461041557806335b16eb81461043357806340452d91146104635761025a565b806318160ddd1161022d57806318160ddd146102fb5780631989c6a814610319578063216ea5ec14610337578063229ba1971461036757806323b872dd146103855761025a565b806301ffc9a71461025f57806306fdde031461028f578063095ea7b3146102ad57806309f28f3c146102dd575b600080fd5b61027960048036038101906102749190612ba7565b61088f565b6040516102869190612d75565b60405180910390f35b610297610a3a565b6040516102a49190612dab565b60405180910390f35b6102c760048036038101906102c29190612b42565b610ac8565b6040516102d49190612d75565b60405180910390f35b6102e5610bec565b6040516102f29190612e2d565b60405180910390f35b610303610c0e565b6040516103109190612e63565b60405180910390f35b610321610c14565b60405161032e9190612e63565b60405180910390f35b610351600480360381019061034c9190612c22565b610c20565b60405161035e9190612e63565b60405180910390f35b61036f610ca6565b60405161037c9190612e63565b60405180910390f35b61039f600480360381019061039a9190612af3565b610cca565b6040516103ac9190612d75565b60405180910390f35b6103cf60048036038101906103ca9190612aca565b610df4565b6040516103dc9190612d75565b60405180910390f35b6103ff60048036038101906103fa9190612c22565b610ee7565b60405161040c9190612e63565b60405180910390f35b61041d610f98565b60405161042a9190612e63565b60405180910390f35b61044d60048036038101906104489190612aca565b610f9e565b60405161045a9190612d75565b60405180910390f35b61047d60048036038101906104789190612bf9565b6111c4565b60405161048a9190612d90565b60405180910390f35b6104ad60048036038101906104a89190612b7e565b6111e8565b6040516104ba9190612e63565b60405180910390f35b6104dd60048036038101906104d89190612b42565b611219565b6040516104ea9190612d75565b60405180910390f35b61050d60048036038101906105089190612aca565b61131b565b60405161051a9190612e63565b60405180910390f35b61053d60048036038101906105389190612bf9565b611373565b60405161054a9190612e63565b60405180910390f35b61055b6113d3565b6040516105689190612e63565b60405180910390f35b61058b60048036038101906105869190612bf9565b6113d9565b6040516105989190612e63565b60405180910390f35b6105bb60048036038101906105b69190612bf9565b611445565b6040516105c89190612e63565b60405180910390f35b6105eb60048036038101906105e69190612aca565b611466565b6040516105f89190612e63565b60405180910390f35b61061b60048036038101906106169190612b7e565b6114d1565b6040516106289190612e63565b60405180910390f35b61064b60048036038101906106469190612aca565b611504565b6040516106589190612e63565b60405180910390f35b6106696115e5565b6040516106769190612d75565b60405180910390f35b610687611793565b6040516106949190612d75565b60405180910390f35b6106a561193a565b6040516106b29190612d5a565b60405180910390f35b6106c3611960565b6040516106d09190612d75565b60405180910390f35b6106e1611b17565b6040516106ee9190612dab565b60405180910390f35b610711600480360381019061070c9190612aca565b611ba5565b60405161071e9190612d75565b60405180910390f35b610741600480360381019061073c9190612b7e565b611c62565b60405161074e9190612e63565b60405180910390f35b61075f611c8e565b60405161076c9190612e2d565b60405180910390f35b61078f600480360381019061078a9190612b42565b611cb0565b60405161079c9190612d75565b60405180910390f35b6107ad611d50565b6040516107ba9190612e63565b60405180910390f35b6107dd60048036038101906107d89190612b7e565b611d74565b6040516107ea9190612e63565b60405180910390f35b61080d60048036038101906108089190612c22565b611d88565b60405161081a9190612e63565b60405180910390f35b61082b611e39565b6040516108389190612e2d565b60405180910390f35b610849611ea3565b6040516108569190612e63565b60405180910390f35b61087960048036038101906108749190612aca565b611ec7565b6040516108869190612d75565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156108e45760019050610a35565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156109375760019050610a35565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561098a5760019050610a35565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156109dd5760019050610a35565b6337a47be47c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610a305760019050610a35565b600090505b919050565b60058054610a47906130c2565b80601f0160208091040260200160405190810160405280929190818152602001828054610a73906130c2565b8015610ac05780601f10610a9557610100808354040283529160200191610ac0565b820191906000526020600020905b815481529060010190602001808311610aa357829003601f168201915b505050505081565b600080610ad3611960565b50610add33610f9e565b50610ae7836113d9565b905080600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610b759190612e9a565b925050819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610bd99190612e63565b60405180910390a3600191505092915050565b600260009054906101000a90046fffffffffffffffffffffffffffffffff1681565b60085481565b60008080549050905090565b600080600080851415610c68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5f90612dcd565b60405180910390fd5b838510610c7457600080fd5b8484610c809190612ef0565b91508482610c8e9190612f21565b90508084610c9c9190612faf565b9250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000610cd7611960565b50610ce133610f9e565b50610ceb846113d9565b915081600b60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610d7657600080fd5b610d81868684611f69565b90508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051610de09190612e63565b60405180910390a380925050509392505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610e7d57503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b610e8657600080fd5b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000806000620f424091506d04ee2d6d415b85acef81000000007f0000000000000000000000000000000000000000000000000000000000000000610f2c9190612ef0565b905060005b84811015610f7357620f42408284610f499190612f21565b610f539190612ef0565b83610f5e9190612faf565b92508080610f6b906130f4565b915050610f31565b50620f42408583610f849190612f21565b610f8e9190612ef0565b9250505092915050565b60075481565b600080600080600080600080610fb389611466565b91506000821480610fdd5750610fc7611e39565b6fffffffffffffffffffffffffffffffff168210155b15610ff25760009750505050505050506111bf565b60006001836110019190612faf565b81548110611038577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154965061104e876111e8565b945060008514156110695760009750505050505050506111bf565b61107287611c62565b955061107d876114d1565b90506d04ee2d6d415b85acef8100000000620f42407f00000000000000000000000000000000000000000000000000000000000000006110bd9190612ef0565b86886110c99190612ef0565b6110d39190612f21565b6110dd9190612ef0565b9350620f424081856110ef9190612f21565b6110f99190612ef0565b92506cffffffff00000000000000000019600102600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282541692505081905550611163898461200d565b50818973ffffffffffffffffffffffffffffffffffffffff167f9a2a887706623ad3ff7fc85652deeceabe9fe1e00466c597972079ee91ea40d3856040516111ab9190612e63565b60405180910390a360019750505050505050505b919050565b600081815481106111d457600080fd5b906000526020600020016000915090505481565b6000606860ff16710fffffffff00000000000000000000000000836001900416908060020a82049150509050919050565b600080600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661127257600080fd5b61127a611960565b5082905082600860008282546112909190612e9a565b925050819055506112a1848261200d565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8856040516112ff9190612e63565b60405180910390a361130f612169565b50600191505092915050565b600068ffffffffffffffffff600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460019004169050919050565b60007f0000000000000000000000000000000000000000000000000000000000000000826113a19190612f21565b7f00000000000000000000000000000000000000000000000000000000000000006113cc9190612e9a565b9050919050565b60095481565b6000600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16620f42406d04ee2d6d415b85acef81000000008461142a9190612f21565b6114349190612f21565b61143e9190612ef0565b9050919050565b6000603c82426114559190612faf565b61145f9190612ef0565b9050919050565b6000604860ff166cffffffff000000000000000000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546001900416908060020a82049150509050919050565b6000608c60ff1673fffff00000000000000000000000000000000000836001900416908060020a82049150509050919050565b6000806000806115138561131b565b9250600260109054906101000a90046fffffffffffffffffffffffffffffffff1661153c611e39565b6115469190612f7b565b6fffffffffffffffffffffffffffffffff169050611594600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1682610ee7565b6fffffffffffffffffffffffffffffffff169150620f42406d04ee2d6d415b85acef81000000006115c59190612f21565b82846115d19190612f21565b6115db9190612ef0565b9350505050919050565b60008060008060006115f5611e39565b9350600260109054906101000a90046fffffffffffffffffffffffffffffffff16846116219190612f7b565b92506000836fffffffffffffffffffffffffffffffff16141561164b576000945050505050611790565b600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16915061169a82846fffffffffffffffffffffffffffffffff16610ee7565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083600260106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555081836fffffffffffffffffffffffffffffffff16856fffffffffffffffffffffffffffffffff167fa0717e54e02bd9829db5e6e998aec0ae9de796b8d150a3cc46a92ab869697755600260009054906101000a90046fffffffffffffffffffffffffffffffff1660405161177f9190612e48565b60405180910390a460019450505050505b90565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117f057600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806000806000611979612251565b995060006001028a141561199a5760009a5050505050505050505050611b14565b6119a38a611d74565b97506001886119b29190612e9a565b90506119bd88611373565b91506119c76115e5565b50600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169450611a0482611445565b92506000831115611a39576d04ee2d6d415b85acef8100000000611a288685611d88565b611a329190612ef0565b9350611a56565b6d04ee2d6d415b85acef810000000085611a539190612ef0565b93505b611a6560008560085484612381565b98506000899080600181540180825580915050600190039060005260206000200160009091909190915055611a998a6111e8565b96506000871415611ab457611aad8a61240d565b9550611ace565b611ac087600854610c20565b9550611acc8689612600565b505b7f55d243082e019fce4009ccea5368b92e436c17586a1e793c7deda16df4e5d67581604051611afd9190612e63565b60405180910390a160019a50505050505050505050505b90565b60068054611b24906130c2565b80601f0160208091040260200160405190810160405280929190818152602001828054611b50906130c2565b8015611b9d5780601f10611b7257610100808354040283529160200191611b9d565b820191906000526020600020905b815481529060010190602001808311611b8057829003601f168201915b505050505081565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c0157600080fd5b6001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000602060ff166cffffffffffffffffff00000000836001900416908060020a82049150509050919050565b600260109054906101000a90046fffffffffffffffffffffffffffffffff1681565b6000806000611cbd611960565b50611cc733610f9e565b50611cd1846113d9565b9150611cde338684611f69565b90508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051611d3d9190612e63565b60405180910390a3809250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600063ffffffff8260019004169050919050565b6000806000620f424091506d04ee2d6d415b85acef81000000007f0000000000000000000000000000000000000000000000000000000000000000611dcd9190612ef0565b905060005b84811015611e1457620f42408284611dea9190612f21565b611df49190612ef0565b83611dff9190612e9a565b92508080611e0c906130f4565b915050611dd2565b50620f42408583611e259190612f21565b611e2f9190612ef0565b9250505092915050565b600060017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000042611e8a9190612faf565b611e949190612ef0565b611e9e9190612e9a565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f2357600080fd5b81600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550919050565b600080611f768584612736565b50611f81848461200d565b50611f8a611e39565b6fffffffffffffffffffffffffffffffff1690506009548310158015611fb8575080611fb586611466565b14155b8015611ff057508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b1561200157611fff8582612867565b505b60019150509392505050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600190049050600085141561206e5760009350505050612163565b6120778661131b565b925084836120859190612e9a565b91508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16116120f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ec90612e0d565b60405180910390fd5b68ffffffffffffffffff198116905068ffffffffffffffffff82168117905080600102600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b600080600060016000805490506121809190612faf565b815481106121b7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001546001900490506cffffffffffffffffff000000001981169050602060ff166008549060020a028117905080600102600060016000805490506122049190612faf565b8154811061223b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550600191505090565b60008060008060016000805490506122699190612faf565b815481106122a0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015491503073ffffffffffffffffffffffffffffffffffffffff1663e80952956040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561230f57600080fd5b505afa158015612323573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123479190612bd0565b6fffffffffffffffffffffffffffffffff16905061236482611d74565b81116123785760006001029250505061237e565b81925050505b90565b60008073fffff00000000000000000000000000000000000608c60ff16869060020a021660010281179050710fffffffff00000000000000000000000000606860ff16879060020a0216600102811790506cffffffffffffffffff00000000602060ff16859060020a02166001028117905063ffffffff83166001028117905080915050949350505050565b600080600080600061241e86611c62565b9350620f42407f0000000000000000000000000000000000000000000000000000000000000000856124509190612f21565b61245a9190612ef0565b91507f0000000000000000000000000000000000000000000000000000000000000000620f42408361248c9190612f21565b6124969190612ef0565b9050838110156125ae576124a986611d74565b9250710fffffffff000000000000000000000000001960010260006001856124d19190612faf565b81548110612508577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160008282541692505081905550606860ff1660019060020a027f800000000000000000000000000000000000000000000000000000000000000017600102600060018561255f9190612faf565b81548110612596577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001600082825417925050819055505b6125f3600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166d04ee2d6d415b85acef8100000000846125ee9190612ef0565b61200d565b5081945050505050919050565b6000806000841415612616576000915050612730565b7f800000000000000000000000000000000000000000000000000000000000000060010260006001856126499190612faf565b81548110612680577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001600082825417925050819055506126f060006001856126a99190612faf565b815481106126e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154611c62565b9050612729600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685836127249190612faf565b61200d565b5060019150505b92915050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460019004905060008514156127975760009350505050612861565b6127a08661131b565b9250848310156127e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127dc90612ded565b60405180910390fd5b84836127f19190612faf565b915068ffffffffffffffffff198116905068ffffffffffffffffff82168117905080600102600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b60006cffffffff00000000000000000019600102600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825416925050819055506cffffffff000000000000000000604860ff16839060020a0216600102600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282541792505081905550612938612943565b506001905092915050565b6000806000806000600160008054905061295d9190612faf565b81548110612994577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154925060016129ac846111e8565b6129b69190612e9a565b905082600190049150710fffffffff000000000000000000000000001982169150710fffffffff00000000000000000000000000606860ff16829060020a0216821791508160010260006001600080549050612a129190612faf565b81548110612a49577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055506001935050505090565b600081359050612a7081613256565b92915050565b600081359050612a858161326d565b92915050565b600081359050612a9a81613284565b92915050565b600081519050612aaf8161329b565b92915050565b600081359050612ac4816132b2565b92915050565b600060208284031215612adc57600080fd5b6000612aea84828501612a61565b91505092915050565b600080600060608486031215612b0857600080fd5b6000612b1686828701612a61565b9350506020612b2786828701612a61565b9250506040612b3886828701612ab5565b9150509250925092565b60008060408385031215612b5557600080fd5b6000612b6385828601612a61565b9250506020612b7485828601612ab5565b9150509250929050565b600060208284031215612b9057600080fd5b6000612b9e84828501612a76565b91505092915050565b600060208284031215612bb957600080fd5b6000612bc784828501612a8b565b91505092915050565b600060208284031215612be257600080fd5b6000612bf084828501612aa0565b91505092915050565b600060208284031215612c0b57600080fd5b6000612c1984828501612ab5565b91505092915050565b60008060408385031215612c3557600080fd5b6000612c4385828601612ab5565b9250506020612c5485828601612ab5565b9150509250929050565b612c6781612fe3565b82525050565b612c7681612ff5565b82525050565b612c8581613001565b82525050565b6000612c9682612e7e565b612ca08185612e89565b9350612cb081856020860161308f565b612cb9816131ca565b840191505092915050565b6000612cd1601183612e89565b9150612cdc826131db565b602082019050919050565b6000612cf4600d83612e89565b9150612cff82613204565b602082019050919050565b6000612d17600d83612e89565b9150612d228261322d565b602082019050919050565b612d3681613037565b82525050565b612d458161307d565b82525050565b612d5481613073565b82525050565b6000602082019050612d6f6000830184612c5e565b92915050565b6000602082019050612d8a6000830184612c6d565b92915050565b6000602082019050612da56000830184612c7c565b92915050565b60006020820190508181036000830152612dc58184612c8b565b905092915050565b60006020820190508181036000830152612de681612cc4565b9050919050565b60006020820190508181036000830152612e0681612ce7565b9050919050565b60006020820190508181036000830152612e2681612d0a565b9050919050565b6000602082019050612e426000830184612d2d565b92915050565b6000602082019050612e5d6000830184612d3c565b92915050565b6000602082019050612e786000830184612d4b565b92915050565b600081519050919050565b600082825260208201905092915050565b6000612ea582613073565b9150612eb083613073565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612ee557612ee461313d565b5b828201905092915050565b6000612efb82613073565b9150612f0683613073565b925082612f1657612f1561316c565b5b828204905092915050565b6000612f2c82613073565b9150612f3783613073565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612f7057612f6f61313d565b5b828202905092915050565b6000612f8682613037565b9150612f9183613037565b925082821015612fa457612fa361313d565b5b828203905092915050565b6000612fba82613073565b9150612fc583613073565b925082821015612fd857612fd761313d565b5b828203905092915050565b6000612fee82613053565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061308882613037565b9050919050565b60005b838110156130ad578082015181840152602081019050613092565b838111156130bc576000848401525b50505050565b600060028204905060018216806130da57607f821691505b602082108114156130ee576130ed61319b565b5b50919050565b60006130ff82613073565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156131325761313161313d565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f4552525f4e554d50415254535f5a45524f000000000000000000000000000000600082015250565b7f4552525f4f5645525350454e4400000000000000000000000000000000000000600082015250565b7f4552525f574f554c445752415000000000000000000000000000000000000000600082015250565b61325f81612fe3565b811461326a57600080fd5b50565b61327681613001565b811461328157600080fd5b50565b61328d8161300b565b811461329857600080fd5b50565b6132a481613037565b81146132af57600080fd5b50565b6132bb81613073565b81146132c657600080fd5b5056fea2646970667358221220310d576c967c2887d9c1152479ae7c4cead1fc0b53e589dddb6047fa4997750064736f6c63430008040033 +\ No newline at end of file diff --git a/python/sarafu_token/data/RedistributedDemurrageToken.json b/python/erc20_demurrage_token/data/DemurrageTokenMultiNocap.json diff --git a/python/sarafu_token/data/__init__.py b/python/erc20_demurrage_token/data/__init__.py diff --git a/python/erc20_demurrage_token/runnable/deploy.py b/python/erc20_demurrage_token/runnable/deploy.py @@ -0,0 +1,135 @@ +"""Deploy sarafu token + +.. moduleauthor:: Louis Holbrook <dev@holbrook.no> +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# standard imports +import sys +import os +import json +import argparse +import logging + +# third-party imports +from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer +from crypto_dev_signer.keystore.dict import DictKeystore +from chainlib.chain import ChainSpec +from chainlib.eth.nonce import ( + RPCNonceOracle, + OverrideNonceOracle, + ) +from chainlib.eth.gas import ( + RPCGasOracle, + OverrideGasOracle, + ) +from chainlib.eth.connection import EthHTTPConnection +from chainlib.eth.tx import receipt +from chainlib.eth.constant import ZERO_ADDRESS + +# local imports +from erc20_demurrage_token import DemurrageToken + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + +script_dir = os.path.dirname(__file__) +data_dir = os.path.join(script_dir, '..', 'data') + +argparser = argparse.ArgumentParser() +argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)') +argparser.add_argument('-w', action='store_true', help='Wait for the last transaction to be confirmed') +argparser.add_argument('-ww', action='store_true', help='Wait for every transaction to be confirmed') +argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='evm:ethereum:1', help='Chain specification string') +argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing') +argparser.add_argument('-v', action='store_true', help='Be verbose') +argparser.add_argument('-vv', action='store_true', help='Be more verbose') +argparser.add_argument('-d', action='store_true', help='Dump RPC calls to terminal and do not send') +argparser.add_argument('--name', type=str, help='Token name') +argparser.add_argument('--decimals', default=6, type=int, help='Token decimals') +argparser.add_argument('--gas-price', type=int, dest='gas_price', help='Override gas price') +argparser.add_argument('--nonce', type=int, help='Override transaction nonce') +argparser.add_argument('--sink-address', default=ZERO_ADDRESS, type=str, help='demurrage level,ppm per minute') +argparser.add_argument('--redistribution-period', default=10080, type=int, help='redistribution period, minutes') # default 10080 = week +argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration') +argparser.add_argument('symbol', default='SRF', type=str, help='Token symbol') +argparser.add_argument('demurrage_level', type=int, help='demurrage level, ppm per minute') +args = argparser.parse_args() + +if args.vv: + logg.setLevel(logging.DEBUG) +elif args.v: + logg.setLevel(logging.INFO) + +block_last = args.w +block_all = args.ww + +passphrase_env = 'ETH_PASSPHRASE' +if args.env_prefix != None: + passphrase_env = args.env_prefix + '_' + passphrase_env +passphrase = os.environ.get(passphrase_env) +if passphrase == None: + logg.warning('no passphrase given') + passphrase='' + +signer_address = None +keystore = DictKeystore() +if args.y != None: + logg.debug('loading keystore file {}'.format(args.y)) + signer_address = keystore.import_keystore_file(args.y, password=passphrase) + logg.debug('now have key for signer address {}'.format(signer_address)) +signer = EIP155Signer(keystore) + +chain_spec = ChainSpec.from_chain_str(args.i) + +rpc = EthHTTPConnection(args.p) +nonce_oracle = None +if args.nonce != None: + nonce_oracle = OverrideNonceOracle(signer_address, args.nonce) +else: + nonce_oracle = RPCNonceOracle(signer_address, rpc) + +gas_oracle = None +if args.gas_price !=None: + gas_oracle = OverrideGasOracle(price=args.gas_price, conn=rpc, code_callback=DemurrageToken.gas) +else: + gas_oracle = RPCGasOracle(rpc, code_callback=DemurrageToken.gas) + +dummy = args.d + +token_name = args.name +if token_name == None: + token_name = args.symbol + +def main(): + c = DemurrageToken(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.constructor( + signer_address, + token_name, + args.symbol, + args.decimals, + args.demurrage_level, + args.redistribution_period, + args.sink_address, + ) + if dummy: + print(tx_hash_hex) + print(o) + else: + rpc.do(o) + if block_last: + r = rpc.wait(tx_hash_hex) + if r['status'] == 0: + sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you') + sys.exit(1) + # TODO: pass through translator for keys (evm tester uses underscore instead of camelcase) + address = r['contractAddress'] + + print(address) + else: + print(tx_hash_hex) + + +if __name__ == '__main__': + main() diff --git a/python/erc20_demurrage_token/token.py b/python/erc20_demurrage_token/token.py @@ -0,0 +1,128 @@ +# standard imports +import os +import logging + +# external imports +from chainlib.eth.tx import ( + TxFactory, + TxFormat, + ) +from chainlib.hash import keccak256_string_to_hex +from chainlib.eth.contract import ( + ABIContractEncoder, + ABIContractType, + abi_decode_single, + ) +from chainlib.eth.constant import ZERO_ADDRESS +from chainlib.jsonrpc import jsonrpc_template +from eth_erc20 import ERC20 +from hexathon import ( + add_0x, + strip_0x, + ) + +# local imports +from erc20_demurrage_token.data import data_dir + +logg = logging.getLogger(__name__) + + +class DemurrageTokenSettings: + + def __init__(self): + self.name = None + self.symbol = None + self.decimals = None + self.demurrage_level = None + self.period_minutes = None + self.sink_address = None + + +class DemurrageToken(ERC20): + + __abi = None + __bytecode = None + + def constructor(self, sender_address, settings, redistribute=True, cap=0, tx_format=TxFormat.JSONRPC): + if not redistribute or cap: + raise NotImplementedError('token cap and sink only redistribution not yet implemented') + code = DemurrageToken.bytecode() + enc = ABIContractEncoder() + enc.string(settings.name) + enc.string(settings.symbol) + enc.uint256(settings.decimals) + enc.uint256(settings.demurrage_level) + enc.uint256(settings.period_minutes) + enc.address(settings.sink_address) + code += enc.get() + tx = self.template(sender_address, None, use_nonce=True) + tx = self.set_code(tx, code) + return self.finalize(tx, tx_format) + + + @staticmethod + def gas(code=None): + return 3500000 + + @staticmethod + def abi(): + if DemurrageToken.__abi == None: + f = open(os.path.join(data_dir, 'DemurrageTokenMultiNocap.json'), 'r') + DemurrageToken.__abi = json.load(f) + f.close() + return DemurrageToken.__abi + + + @staticmethod + def bytecode(): + if DemurrageToken.__bytecode == None: + f = open(os.path.join(data_dir, 'DemurrageTokenMultiNocap.bin'), 'r') + DemurrageToken.__bytecode = f.read() + f.close() + return DemurrageToken.__bytecode + + + def add_minter(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('addMinter') + enc.typ(ABIContractType.ADDRESS) + enc.address(address) + data = enc.get() + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format) + return tx + + + def mint_to(self, contract_address, sender_address, address, value, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('mintTo') + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.UINT256) + enc.address(address) + enc.uint256(value) + data = enc.get() + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format) + return tx + + + def apply_demurrage(self, contract_address, sender_address): + return self.transact_noarg('applyDemurrage', contract_address, sender_address) + + + def actual_period(self, contract_address, sender_address=ZERO_ADDRESS): + return self.call_noarg('actualPeriod', contract_address, sender_address=sender_address) + + + def demurrage_amount(self, contract_address, sender_address=ZERO_ADDRESS): + return self.call_noarg('demurrageAmount', contract_address, sender_address=sender_address) + + + def parse_actual_period(self, v): + return abi_decode_single(ABIContractType.UINT256, v) + + + def parse_demurrage_amount(self, v): + return abi_decode_single(ABIContractType.UINT256, v) diff --git a/python/requirements.txt b/python/requirements.txt @@ -1,3 +1,3 @@ -chainlib~=0.0.3a1 -eth-erc20~=0.0.9a1 +chainlib~=0.0.3rc2 +eth-erc20~=0.0.9a3 crypto-dev-signer~=0.4.14b3 diff --git a/python/sarafu_token/__init__.py b/python/sarafu_token/__init__.py @@ -1 +0,0 @@ -from .token import RedistributedDemurrageToken diff --git a/python/sarafu_token/data/RedistributedDemurrageToken.bin b/python/sarafu_token/data/RedistributedDemurrageToken.bin @@ -1 +0,0 @@ -60e06040523480156200001157600080fd5b5060405162003d0238038062003d0283398181016040528101906200003791906200048e565b33600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600a6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555085600590805190602001906200010a92919062000327565b5084600690805190602001906200012392919062000327565b508360ff166007819055504260808181525050603c826200014591906200074d565b60a08181525050620f42406d04ee2d6d415b85acef81000000006200016b91906200074d565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506001600260106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508260c0818152505060006200020a6000620f4240600060016200029b640100000000026401000000009004565b9050600081908060018154018082558091505060019003906000526020600020016000909190919091505581600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460ff16600a62000288919062000610565b6009819055505050505050505062000994565b60008073fffff00000000000000000000000000000000000608c60ff16869060020a021660010281179050710fffffffff00000000000000000000000000606860ff16879060020a0216600102811790506cffffffffffffffffff00000000602060ff16859060020a02166001028117905063ffffffff83166001028117905080915050949350505050565b82805462000335906200082f565b90600052602060002090601f016020900481019282620003595760008555620003a5565b82601f106200037457805160ff1916838001178555620003a5565b82800160010185558215620003a5579182015b82811115620003a457825182559160200191906001019062000387565b5b509050620003b49190620003b8565b5090565b5b80821115620003d3576000816000905550600101620003b9565b5090565b6000620003ee620003e8846200057f565b62000556565b9050828152602081018484840111156200040757600080fd5b62000414848285620007f9565b509392505050565b6000815190506200042d8162000946565b92915050565b600082601f8301126200044557600080fd5b815162000457848260208601620003d7565b91505092915050565b600081519050620004718162000960565b92915050565b60008151905062000488816200097a565b92915050565b60008060008060008060c08789031215620004a857600080fd5b600087015167ffffffffffffffff811115620004c357600080fd5b620004d189828a0162000433565b965050602087015167ffffffffffffffff811115620004ef57600080fd5b620004fd89828a0162000433565b95505060406200051089828a0162000477565b94505060606200052389828a0162000460565b93505060806200053689828a0162000460565b92505060a06200054989828a016200041c565b9150509295509295509295565b60006200056262000575565b905062000570828262000865565b919050565b6000604051905090565b600067ffffffffffffffff8211156200059d576200059c620008f9565b5b620005a88262000928565b9050602081019050919050565b6000808291508390505b60018511156200060757808604811115620005df57620005de6200089b565b5b6001851615620005ef5780820291505b8081029050620005ff8562000939565b9450620005bf565b94509492505050565b60006200061d82620007e2565b91506200062a83620007e2565b9250620006597fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000661565b905092915050565b60008262000673576001905062000746565b8162000683576000905062000746565b81600181146200069c5760028114620006a757620006dd565b600191505062000746565b60ff841115620006bc57620006bb6200089b565b5b8360020a915084821115620006d657620006d56200089b565b5b5062000746565b5060208310610133831016604e8410600b8410161715620007175782820a9050838111156200071157620007106200089b565b5b62000746565b620007268484846001620005b5565b9250905081840481111562000740576200073f6200089b565b5b81810290505b9392505050565b60006200075a82620007e2565b91506200076783620007e2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615620007a357620007a26200089b565b5b828202905092915050565b6000620007bb82620007c2565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101562000819578082015181840152602081019050620007fc565b8381111562000829576000848401525b50505050565b600060028204905060018216806200084857607f821691505b602082108114156200085f576200085e620008ca565b5b50919050565b620008708262000928565b810181811067ffffffffffffffff82111715620008925762000891620008f9565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6000600282049050919050565b6200095181620007ae565b81146200095d57600080fd5b50565b6200096b81620007e2565b81146200097757600080fd5b50565b6200098581620007ec565b81146200099157600080fd5b50565b60805160a05160c0516132ff62000a0360003960008181610ca801528181610f030152818161109401528181611da401528181612426015261245e01526000818161137701528181611d520152611e3f0152600081816113a301528181611e600152611ea501526132ff6000f3fe608060405234801561001057600080fd5b506004361061025a576000357c0100000000000000000000000000000000000000000000000000000000900480636787a9be11610158578063983b2d56116100d5578063e3ab207a11610099578063e3ab207a146107c3578063e54d63f7146107f3578063e809529514610823578063eda4e6d614610841578063f2fde38b1461085f5761025a565b8063983b2d56146106f75780639da7d8ba14610727578063a2119e2f14610757578063a9059cbb14610775578063b470aade146107a55761025a565b8063731f237c1161011c578063731f237c1461066157806379ba50971461067f5780638da5cb5b1461069d5780638f1df6bc146106bb57806395d89b41146106d95761025a565b80636787a9be146105715780636a2d094e146105a15780636d5055a6146105d15780636ffa8a051461060157806370a08231146106315761025a565b80633092afd5116101e657806340fc89f5116101aa57806340fc89f514610493578063449a52f8146104c357806347a50517146104f35780634abfbba214610523578063573cc507146105535761025a565b80633092afd5146103b557806331333487146103e5578063313ce5671461041557806335b16eb81461043357806340452d91146104635761025a565b806318160ddd1161022d57806318160ddd146102fb5780631989c6a814610319578063216ea5ec14610337578063229ba1971461036757806323b872dd146103855761025a565b806301ffc9a71461025f57806306fdde031461028f578063095ea7b3146102ad57806309f28f3c146102dd575b600080fd5b61027960048036038101906102749190612ba7565b61088f565b6040516102869190612d75565b60405180910390f35b610297610a3a565b6040516102a49190612dab565b60405180910390f35b6102c760048036038101906102c29190612b42565b610ac8565b6040516102d49190612d75565b60405180910390f35b6102e5610bec565b6040516102f29190612e2d565b60405180910390f35b610303610c0e565b6040516103109190612e63565b60405180910390f35b610321610c14565b60405161032e9190612e63565b60405180910390f35b610351600480360381019061034c9190612c22565b610c20565b60405161035e9190612e63565b60405180910390f35b61036f610ca6565b60405161037c9190612e63565b60405180910390f35b61039f600480360381019061039a9190612af3565b610cca565b6040516103ac9190612d75565b60405180910390f35b6103cf60048036038101906103ca9190612aca565b610df4565b6040516103dc9190612d75565b60405180910390f35b6103ff60048036038101906103fa9190612c22565b610ee7565b60405161040c9190612e63565b60405180910390f35b61041d610f98565b60405161042a9190612e63565b60405180910390f35b61044d60048036038101906104489190612aca565b610f9e565b60405161045a9190612d75565b60405180910390f35b61047d60048036038101906104789190612bf9565b6111c4565b60405161048a9190612d90565b60405180910390f35b6104ad60048036038101906104a89190612b7e565b6111e8565b6040516104ba9190612e63565b60405180910390f35b6104dd60048036038101906104d89190612b42565b611219565b6040516104ea9190612d75565b60405180910390f35b61050d60048036038101906105089190612aca565b61131b565b60405161051a9190612e63565b60405180910390f35b61053d60048036038101906105389190612bf9565b611373565b60405161054a9190612e63565b60405180910390f35b61055b6113d3565b6040516105689190612e63565b60405180910390f35b61058b60048036038101906105869190612bf9565b6113d9565b6040516105989190612e63565b60405180910390f35b6105bb60048036038101906105b69190612bf9565b611445565b6040516105c89190612e63565b60405180910390f35b6105eb60048036038101906105e69190612aca565b611466565b6040516105f89190612e63565b60405180910390f35b61061b60048036038101906106169190612b7e565b6114d1565b6040516106289190612e63565b60405180910390f35b61064b60048036038101906106469190612aca565b611504565b6040516106589190612e63565b60405180910390f35b6106696115e5565b6040516106769190612d75565b60405180910390f35b610687611793565b6040516106949190612d75565b60405180910390f35b6106a561193a565b6040516106b29190612d5a565b60405180910390f35b6106c3611960565b6040516106d09190612d75565b60405180910390f35b6106e1611b17565b6040516106ee9190612dab565b60405180910390f35b610711600480360381019061070c9190612aca565b611ba5565b60405161071e9190612d75565b60405180910390f35b610741600480360381019061073c9190612b7e565b611c62565b60405161074e9190612e63565b60405180910390f35b61075f611c8e565b60405161076c9190612e2d565b60405180910390f35b61078f600480360381019061078a9190612b42565b611cb0565b60405161079c9190612d75565b60405180910390f35b6107ad611d50565b6040516107ba9190612e63565b60405180910390f35b6107dd60048036038101906107d89190612b7e565b611d74565b6040516107ea9190612e63565b60405180910390f35b61080d60048036038101906108089190612c22565b611d88565b60405161081a9190612e63565b60405180910390f35b61082b611e39565b6040516108389190612e2d565b60405180910390f35b610849611ea3565b6040516108569190612e63565b60405180910390f35b61087960048036038101906108749190612aca565b611ec7565b6040516108869190612d75565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156108e45760019050610a35565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156109375760019050610a35565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561098a5760019050610a35565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156109dd5760019050610a35565b6337a47be47c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610a305760019050610a35565b600090505b919050565b60058054610a47906130c2565b80601f0160208091040260200160405190810160405280929190818152602001828054610a73906130c2565b8015610ac05780601f10610a9557610100808354040283529160200191610ac0565b820191906000526020600020905b815481529060010190602001808311610aa357829003601f168201915b505050505081565b600080610ad3611960565b50610add33610f9e565b50610ae7836113d9565b905080600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610b759190612e9a565b925050819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610bd99190612e63565b60405180910390a3600191505092915050565b600260009054906101000a90046fffffffffffffffffffffffffffffffff1681565b60085481565b60008080549050905090565b600080600080851415610c68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5f90612dcd565b60405180910390fd5b838510610c7457600080fd5b8484610c809190612ef0565b91508482610c8e9190612f21565b90508084610c9c9190612faf565b9250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000610cd7611960565b50610ce133610f9e565b50610ceb846113d9565b915081600b60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610d7657600080fd5b610d81868684611f69565b90508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051610de09190612e63565b60405180910390a380925050509392505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610e7d57503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b610e8657600080fd5b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000806000620f424091506d04ee2d6d415b85acef81000000007f0000000000000000000000000000000000000000000000000000000000000000610f2c9190612ef0565b905060005b84811015610f7357620f42408284610f499190612f21565b610f539190612ef0565b83610f5e9190612faf565b92508080610f6b906130f4565b915050610f31565b50620f42408583610f849190612f21565b610f8e9190612ef0565b9250505092915050565b60075481565b600080600080600080600080610fb389611466565b91506000821480610fdd5750610fc7611e39565b6fffffffffffffffffffffffffffffffff168210155b15610ff25760009750505050505050506111bf565b60006001836110019190612faf565b81548110611038577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154965061104e876111e8565b945060008514156110695760009750505050505050506111bf565b61107287611c62565b955061107d876114d1565b90506d04ee2d6d415b85acef8100000000620f42407f00000000000000000000000000000000000000000000000000000000000000006110bd9190612ef0565b86886110c99190612ef0565b6110d39190612f21565b6110dd9190612ef0565b9350620f424081856110ef9190612f21565b6110f99190612ef0565b92506cffffffff00000000000000000019600102600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282541692505081905550611163898461200d565b50818973ffffffffffffffffffffffffffffffffffffffff167f9a2a887706623ad3ff7fc85652deeceabe9fe1e00466c597972079ee91ea40d3856040516111ab9190612e63565b60405180910390a360019750505050505050505b919050565b600081815481106111d457600080fd5b906000526020600020016000915090505481565b6000606860ff16710fffffffff00000000000000000000000000836001900416908060020a82049150509050919050565b600080600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661127257600080fd5b61127a611960565b5082905082600860008282546112909190612e9a565b925050819055506112a1848261200d565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8856040516112ff9190612e63565b60405180910390a361130f612169565b50600191505092915050565b600068ffffffffffffffffff600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460019004169050919050565b60007f0000000000000000000000000000000000000000000000000000000000000000826113a19190612f21565b7f00000000000000000000000000000000000000000000000000000000000000006113cc9190612e9a565b9050919050565b60095481565b6000600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16620f42406d04ee2d6d415b85acef81000000008461142a9190612f21565b6114349190612f21565b61143e9190612ef0565b9050919050565b6000603c82426114559190612faf565b61145f9190612ef0565b9050919050565b6000604860ff166cffffffff000000000000000000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546001900416908060020a82049150509050919050565b6000608c60ff1673fffff00000000000000000000000000000000000836001900416908060020a82049150509050919050565b6000806000806115138561131b565b9250600260109054906101000a90046fffffffffffffffffffffffffffffffff1661153c611e39565b6115469190612f7b565b6fffffffffffffffffffffffffffffffff169050611594600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1682610ee7565b6fffffffffffffffffffffffffffffffff169150620f42406d04ee2d6d415b85acef81000000006115c59190612f21565b82846115d19190612f21565b6115db9190612ef0565b9350505050919050565b60008060008060006115f5611e39565b9350600260109054906101000a90046fffffffffffffffffffffffffffffffff16846116219190612f7b565b92506000836fffffffffffffffffffffffffffffffff16141561164b576000945050505050611790565b600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16915061169a82846fffffffffffffffffffffffffffffffff16610ee7565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083600260106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555081836fffffffffffffffffffffffffffffffff16856fffffffffffffffffffffffffffffffff167fa0717e54e02bd9829db5e6e998aec0ae9de796b8d150a3cc46a92ab869697755600260009054906101000a90046fffffffffffffffffffffffffffffffff1660405161177f9190612e48565b60405180910390a460019450505050505b90565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117f057600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806000806000611979612251565b995060006001028a141561199a5760009a5050505050505050505050611b14565b6119a38a611d74565b97506001886119b29190612e9a565b90506119bd88611373565b91506119c76115e5565b50600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169450611a0482611445565b92506000831115611a39576d04ee2d6d415b85acef8100000000611a288685611d88565b611a329190612ef0565b9350611a56565b6d04ee2d6d415b85acef810000000085611a539190612ef0565b93505b611a6560008560085484612381565b98506000899080600181540180825580915050600190039060005260206000200160009091909190915055611a998a6111e8565b96506000871415611ab457611aad8a61240d565b9550611ace565b611ac087600854610c20565b9550611acc8689612600565b505b7f55d243082e019fce4009ccea5368b92e436c17586a1e793c7deda16df4e5d67581604051611afd9190612e63565b60405180910390a160019a50505050505050505050505b90565b60068054611b24906130c2565b80601f0160208091040260200160405190810160405280929190818152602001828054611b50906130c2565b8015611b9d5780601f10611b7257610100808354040283529160200191611b9d565b820191906000526020600020905b815481529060010190602001808311611b8057829003601f168201915b505050505081565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c0157600080fd5b6001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000602060ff166cffffffffffffffffff00000000836001900416908060020a82049150509050919050565b600260109054906101000a90046fffffffffffffffffffffffffffffffff1681565b6000806000611cbd611960565b50611cc733610f9e565b50611cd1846113d9565b9150611cde338684611f69565b90508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051611d3d9190612e63565b60405180910390a3809250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600063ffffffff8260019004169050919050565b6000806000620f424091506d04ee2d6d415b85acef81000000007f0000000000000000000000000000000000000000000000000000000000000000611dcd9190612ef0565b905060005b84811015611e1457620f42408284611dea9190612f21565b611df49190612ef0565b83611dff9190612e9a565b92508080611e0c906130f4565b915050611dd2565b50620f42408583611e259190612f21565b611e2f9190612ef0565b9250505092915050565b600060017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000042611e8a9190612faf565b611e949190612ef0565b611e9e9190612e9a565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f2357600080fd5b81600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550919050565b600080611f768584612736565b50611f81848461200d565b50611f8a611e39565b6fffffffffffffffffffffffffffffffff1690506009548310158015611fb8575080611fb586611466565b14155b8015611ff057508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b1561200157611fff8582612867565b505b60019150509392505050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600190049050600085141561206e5760009350505050612163565b6120778661131b565b925084836120859190612e9a565b91508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16116120f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ec90612e0d565b60405180910390fd5b68ffffffffffffffffff198116905068ffffffffffffffffff82168117905080600102600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b600080600060016000805490506121809190612faf565b815481106121b7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001546001900490506cffffffffffffffffff000000001981169050602060ff166008549060020a028117905080600102600060016000805490506122049190612faf565b8154811061223b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550600191505090565b60008060008060016000805490506122699190612faf565b815481106122a0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015491503073ffffffffffffffffffffffffffffffffffffffff1663e80952956040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561230f57600080fd5b505afa158015612323573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123479190612bd0565b6fffffffffffffffffffffffffffffffff16905061236482611d74565b81116123785760006001029250505061237e565b81925050505b90565b60008073fffff00000000000000000000000000000000000608c60ff16869060020a021660010281179050710fffffffff00000000000000000000000000606860ff16879060020a0216600102811790506cffffffffffffffffff00000000602060ff16859060020a02166001028117905063ffffffff83166001028117905080915050949350505050565b600080600080600061241e86611c62565b9350620f42407f0000000000000000000000000000000000000000000000000000000000000000856124509190612f21565b61245a9190612ef0565b91507f0000000000000000000000000000000000000000000000000000000000000000620f42408361248c9190612f21565b6124969190612ef0565b9050838110156125ae576124a986611d74565b9250710fffffffff000000000000000000000000001960010260006001856124d19190612faf565b81548110612508577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160008282541692505081905550606860ff1660019060020a027f800000000000000000000000000000000000000000000000000000000000000017600102600060018561255f9190612faf565b81548110612596577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001600082825417925050819055505b6125f3600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166d04ee2d6d415b85acef8100000000846125ee9190612ef0565b61200d565b5081945050505050919050565b6000806000841415612616576000915050612730565b7f800000000000000000000000000000000000000000000000000000000000000060010260006001856126499190612faf565b81548110612680577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001600082825417925050819055506126f060006001856126a99190612faf565b815481106126e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154611c62565b9050612729600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685836127249190612faf565b61200d565b5060019150505b92915050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460019004905060008514156127975760009350505050612861565b6127a08661131b565b9250848310156127e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127dc90612ded565b60405180910390fd5b84836127f19190612faf565b915068ffffffffffffffffff198116905068ffffffffffffffffff82168117905080600102600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b60006cffffffff00000000000000000019600102600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825416925050819055506cffffffff000000000000000000604860ff16839060020a0216600102600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282541792505081905550612938612943565b506001905092915050565b6000806000806000600160008054905061295d9190612faf565b81548110612994577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154925060016129ac846111e8565b6129b69190612e9a565b905082600190049150710fffffffff000000000000000000000000001982169150710fffffffff00000000000000000000000000606860ff16829060020a0216821791508160010260006001600080549050612a129190612faf565b81548110612a49577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055506001935050505090565b600081359050612a7081613256565b92915050565b600081359050612a858161326d565b92915050565b600081359050612a9a81613284565b92915050565b600081519050612aaf8161329b565b92915050565b600081359050612ac4816132b2565b92915050565b600060208284031215612adc57600080fd5b6000612aea84828501612a61565b91505092915050565b600080600060608486031215612b0857600080fd5b6000612b1686828701612a61565b9350506020612b2786828701612a61565b9250506040612b3886828701612ab5565b9150509250925092565b60008060408385031215612b5557600080fd5b6000612b6385828601612a61565b9250506020612b7485828601612ab5565b9150509250929050565b600060208284031215612b9057600080fd5b6000612b9e84828501612a76565b91505092915050565b600060208284031215612bb957600080fd5b6000612bc784828501612a8b565b91505092915050565b600060208284031215612be257600080fd5b6000612bf084828501612aa0565b91505092915050565b600060208284031215612c0b57600080fd5b6000612c1984828501612ab5565b91505092915050565b60008060408385031215612c3557600080fd5b6000612c4385828601612ab5565b9250506020612c5485828601612ab5565b9150509250929050565b612c6781612fe3565b82525050565b612c7681612ff5565b82525050565b612c8581613001565b82525050565b6000612c9682612e7e565b612ca08185612e89565b9350612cb081856020860161308f565b612cb9816131ca565b840191505092915050565b6000612cd1601183612e89565b9150612cdc826131db565b602082019050919050565b6000612cf4600d83612e89565b9150612cff82613204565b602082019050919050565b6000612d17600d83612e89565b9150612d228261322d565b602082019050919050565b612d3681613037565b82525050565b612d458161307d565b82525050565b612d5481613073565b82525050565b6000602082019050612d6f6000830184612c5e565b92915050565b6000602082019050612d8a6000830184612c6d565b92915050565b6000602082019050612da56000830184612c7c565b92915050565b60006020820190508181036000830152612dc58184612c8b565b905092915050565b60006020820190508181036000830152612de681612cc4565b9050919050565b60006020820190508181036000830152612e0681612ce7565b9050919050565b60006020820190508181036000830152612e2681612d0a565b9050919050565b6000602082019050612e426000830184612d2d565b92915050565b6000602082019050612e5d6000830184612d3c565b92915050565b6000602082019050612e786000830184612d4b565b92915050565b600081519050919050565b600082825260208201905092915050565b6000612ea582613073565b9150612eb083613073565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612ee557612ee461313d565b5b828201905092915050565b6000612efb82613073565b9150612f0683613073565b925082612f1657612f1561316c565b5b828204905092915050565b6000612f2c82613073565b9150612f3783613073565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612f7057612f6f61313d565b5b828202905092915050565b6000612f8682613037565b9150612f9183613037565b925082821015612fa457612fa361313d565b5b828203905092915050565b6000612fba82613073565b9150612fc583613073565b925082821015612fd857612fd761313d565b5b828203905092915050565b6000612fee82613053565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061308882613037565b9050919050565b60005b838110156130ad578082015181840152602081019050613092565b838111156130bc576000848401525b50505050565b600060028204905060018216806130da57607f821691505b602082108114156130ee576130ed61319b565b5b50919050565b60006130ff82613073565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156131325761313161313d565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f4552525f4e554d50415254535f5a45524f000000000000000000000000000000600082015250565b7f4552525f4f5645525350454e4400000000000000000000000000000000000000600082015250565b7f4552525f574f554c445752415000000000000000000000000000000000000000600082015250565b61325f81612fe3565b811461326a57600080fd5b50565b61327681613001565b811461328157600080fd5b50565b61328d8161300b565b811461329857600080fd5b50565b6132a481613037565b81146132af57600080fd5b50565b6132bb81613073565b81146132c657600080fd5b5056fea2646970667358221220879798a75c029f2a28b60631c811b9abb056ffb11a13cc36e1f321111ab2405a64736f6c63430008030033 -\ No newline at end of file diff --git a/python/sarafu_token/runnable/deploy.py b/python/sarafu_token/runnable/deploy.py @@ -1,135 +0,0 @@ -"""Deploy sarafu token - -.. moduleauthor:: Louis Holbrook <dev@holbrook.no> -.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 - -""" - -# standard imports -import sys -import os -import json -import argparse -import logging - -# third-party imports -from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer -from crypto_dev_signer.keystore.dict import DictKeystore -from chainlib.chain import ChainSpec -from chainlib.eth.nonce import ( - RPCNonceOracle, - OverrideNonceOracle, - ) -from chainlib.eth.gas import ( - RPCGasOracle, - OverrideGasOracle, - ) -from chainlib.eth.connection import EthHTTPConnection -from chainlib.eth.tx import receipt -from chainlib.eth.constant import ZERO_ADDRESS - -# local imports -from sarafu_token import RedistributedDemurrageToken - -logging.basicConfig(level=logging.WARNING) -logg = logging.getLogger() - -script_dir = os.path.dirname(__file__) -data_dir = os.path.join(script_dir, '..', 'data') - -argparser = argparse.ArgumentParser() -argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)') -argparser.add_argument('-w', action='store_true', help='Wait for the last transaction to be confirmed') -argparser.add_argument('-ww', action='store_true', help='Wait for every transaction to be confirmed') -argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='evm:ethereum:1', help='Chain specification string') -argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing') -argparser.add_argument('-v', action='store_true', help='Be verbose') -argparser.add_argument('-vv', action='store_true', help='Be more verbose') -argparser.add_argument('-d', action='store_true', help='Dump RPC calls to terminal and do not send') -argparser.add_argument('--name', type=str, help='Token name') -argparser.add_argument('--decimals', default=6, type=int, help='Token decimals') -argparser.add_argument('--gas-price', type=int, dest='gas_price', help='Override gas price') -argparser.add_argument('--nonce', type=int, help='Override transaction nonce') -argparser.add_argument('--sink-address', default=ZERO_ADDRESS, type=str, help='demurrage level,ppm per minute') -argparser.add_argument('--redistribution-period', default=10080, type=int, help='redistribution period, minutes') # default 10080 = week -argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration') -argparser.add_argument('symbol', default='SRF', type=str, help='Token symbol') -argparser.add_argument('demurrage_level', type=int, help='demurrage level, ppm per minute') -args = argparser.parse_args() - -if args.vv: - logg.setLevel(logging.DEBUG) -elif args.v: - logg.setLevel(logging.INFO) - -block_last = args.w -block_all = args.ww - -passphrase_env = 'ETH_PASSPHRASE' -if args.env_prefix != None: - passphrase_env = args.env_prefix + '_' + passphrase_env -passphrase = os.environ.get(passphrase_env) -if passphrase == None: - logg.warning('no passphrase given') - passphrase='' - -signer_address = None -keystore = DictKeystore() -if args.y != None: - logg.debug('loading keystore file {}'.format(args.y)) - signer_address = keystore.import_keystore_file(args.y, password=passphrase) - logg.debug('now have key for signer address {}'.format(signer_address)) -signer = EIP155Signer(keystore) - -chain_spec = ChainSpec.from_chain_str(args.i) - -rpc = EthHTTPConnection(args.p) -nonce_oracle = None -if args.nonce != None: - nonce_oracle = OverrideNonceOracle(signer_address, args.nonce) -else: - nonce_oracle = RPCNonceOracle(signer_address, rpc) - -gas_oracle = None -if args.gas_price !=None: - gas_oracle = OverrideGasOracle(price=args.gas_price, conn=rpc, code_callback=RedistributedDemurrageToken.gas) -else: - gas_oracle = RPCGasOracle(rpc, code_callback=RedistributedDemurrageToken.gas) - -dummy = args.d - -token_name = args.name -if token_name == None: - token_name = args.symbol - -def main(): - c = RedistributedDemurrageToken(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) - (tx_hash_hex, o) = c.constructor( - signer_address, - token_name, - args.symbol, - args.decimals, - args.demurrage_level, - args.redistribution_period, - args.sink_address, - ) - if dummy: - print(tx_hash_hex) - print(o) - else: - rpc.do(o) - if block_last: - r = rpc.wait(tx_hash_hex) - if r['status'] == 0: - sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you') - sys.exit(1) - # TODO: pass through translator for keys (evm tester uses underscore instead of camelcase) - address = r['contractAddress'] - - print(address) - else: - print(tx_hash_hex) - - -if __name__ == '__main__': - main() diff --git a/python/sarafu_token/runnable/legacy/deploy.py b/python/sarafu_token/runnable/legacy/deploy.py @@ -1,133 +0,0 @@ -"""Deploys Sarafu token - -.. moduleauthor:: Louis Holbrook <dev@holbrook.no> -.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 - -""" - -# SPDX-License-Identifier: GPL-3.0-or-later - -# standard imports -import sys -import os -import json -import argparse -import logging -import time -from enum import Enum - -# third-party imports -import web3 -from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer -from crypto_dev_signer.keystore import DictKeystore -from crypto_dev_signer.eth.helper import EthTxExecutor - -logging.basicConfig(level=logging.WARNING) -logg = logging.getLogger() - -logging.getLogger('web3').setLevel(logging.WARNING) -logging.getLogger('urllib3').setLevel(logging.WARNING) - -script_dir = os.path.dirname(__file__) -data_dir = os.path.join(script_dir, '..', '..', 'data') - - -argparser = argparse.ArgumentParser() -argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)') -argparser.add_argument('-w', action='store_true', help='Wait for the last transaction to be confirmed') -argparser.add_argument('-ww', action='store_true', help='Wait for every transaction to be confirmed') -argparser.add_argument('-e', action='store_true', help='Treat all transactions as essential') -argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='Ethereum:1', help='Chain specification string') -argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing') -argparser.add_argument('--name', dest='n', default='Giftable Token', type=str, help='Token name') -argparser.add_argument('--symbol', dest='s', default='GFT', type=str, help='Token symbol') -argparser.add_argument('--decimals', dest='d', default=18, type=int, help='Token decimals') -argparser.add_argument('--minter', action='append', type=str, help='Minter to add') -argparser.add_argument('--sink-address', type=str, help='Sink address (if not set, signer address is used)') -argparser.add_argument('--abi-dir', dest='abi_dir', type=str, default=data_dir, help='Directory containing bytecode and abi (default: {})'.format(data_dir)) - -argparser.add_argument('-v', action='store_true', help='Be verbose') -argparser.add_argument('taxlevel_minute', type=int, help='Tax level per minute in ppm') -argparser.add_argument('period_minutes', type=int, help='Redistribution period, in minutes') -args = argparser.parse_args() - -if args.v: - logg.setLevel(logging.DEBUG) - -block_last = args.w -block_all = args.ww - -w3 = web3.Web3(web3.Web3.HTTPProvider(args.p)) - -signer_address = None -keystore = DictKeystore() -if args.y != None: - logg.debug('loading keystore file {}'.format(args.y)) - signer_address = keystore.import_keystore_file(args.y) - logg.debug('now have key for signer address {}'.format(signer_address)) -signer = EIP155Signer(keystore) - -chain_pair = args.i.split(':') -chain_id = int(chain_pair[1]) - -helper = EthTxExecutor( - w3, - signer_address, - signer, - chain_id, - block=args.ww, - ) -#g = ERC20TxFactory(signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle, chain_id=chain_id) - - -def main(): - - f = open(os.path.join(args.abi_dir, 'RedistributedDemurrageToken.json'), 'r') - abi = json.load(f) - f.close() - - f = open(os.path.join(args.abi_dir, 'RedistributedDemurrageToken.bin'), 'r') - bytecode = f.read() - f.close() - - sink_address = args.sink_address - if sink_address == None: - sink_address = signer_address - - c = w3.eth.contract(abi=abi, bytecode=bytecode) - (tx_hash, rcpt) = helper.sign_and_send( - [ - c.constructor(args.n, args.s, args.d, args.taxlevel_minute, args.period_minutes, sink_address).buildTransaction - ], - force_wait=True, - ) - logg.debug('tx hash {} rcpt {}'.format(tx_hash, rcpt)) - - address = rcpt.contractAddress - logg.debug('token contract mined {} {} {} {}'.format(address, args.n, args.s, args.d, args.taxlevel_minute, args.period_minutes, sink_address)) - c = w3.eth.contract(abi=abi, address=address) - - balance = c.functions.balanceOf(signer_address).call() - logg.info('balance {}: {} {}'.format(signer_address, balance, tx_hash)) - - if args.minter != None: - for a in args.minter: - if a == signer_address: - continue - (tx_hash, rcpt) = helper.sign_and_send( - [ - c.functions.addMinter(a).buildTransaction, - ], - ) - logg.debug('minter add {} {}'.format(a, tx_hash)) - - if block_last: - helper.wait_for() - - print(address) - - sys.exit(0) - - -if __name__ == '__main__': - main() diff --git a/python/sarafu_token/token.py b/python/sarafu_token/token.py @@ -1,87 +0,0 @@ -# standard imports -import os -import logging - -# external imports -from chainlib.eth.tx import ( - TxFactory, - TxFormat, - ) -from chainlib.hash import keccak256_string_to_hex -from chainlib.eth.contract import ( - ABIContractEncoder, - ABIContractType, - ) - -# local imports -from sarafu_token.data import data_dir - -logg = logging.getLogger(__name__) - - -class RedistributedDemurrageToken(TxFactory): - - __abi = None - __bytecode = None - - def constructor(self, sender_address, name, symbol, decimals, demurrage_level, period_minutes, sink_address, tx_format=TxFormat.JSONRPC): - code = RedistributedDemurrageToken.bytecode() - enc = ABIContractEncoder() - enc.string(name) - enc.string(symbol) - enc.uint256(decimals) - enc.uint256(demurrage_level) - enc.uint256(period_minutes) - enc.address(sink_address) - code += enc.get() - tx = self.template(sender_address, None, use_nonce=True) - tx = self.set_code(tx, code) - return self.finalize(tx, tx_format) - - - @staticmethod - def gas(code=None): - return 3500000 - - @staticmethod - def abi(): - if RedistributedDemurrageToken.__abi == None: - f = open(os.path.join(data_dir, 'RedistributedDemurrageToken.json'), 'r') - RedistributedDemurrageToken.__abi = json.load(f) - f.close() - return RedistributedDemurrageToken.__abi - - - @staticmethod - def bytecode(): - if RedistributedDemurrageToken.__bytecode == None: - f = open(os.path.join(data_dir, 'RedistributedDemurrageToken.bin'), 'r') - RedistributedDemurrageToken.__bytecode = f.read() - f.close() - return RedistributedDemurrageToken.__bytecode - - - def add_minter(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC): - enc = ABIContractEncoder() - enc.method('addMinter') - enc.typ(ABIContractType.ADDRESS) - enc.address(address) - data = enc.get() - tx = self.template(sender_address, contract_address, use_nonce=True) - tx = self.set_code(tx, data) - tx = self.finalize(tx, tx_format) - return tx - - - def mint_to(self, contract_address, sender_address, address, value, tx_format=TxFormat.JSONRPC): - enc = ABIContractEncoder() - enc.method('mintTo') - enc.typ(ABIContractType.ADDRESS) - enc.typ(ABIContractType.UINT256) - enc.address(address) - enc.uint256(value) - data = enc.get() - tx = self.template(sender_address, contract_address, use_nonce=True) - tx = self.set_code(tx, data) - tx = self.finalize(tx, tx_format) - return tx diff --git a/python/setup.cfg b/python/setup.cfg @@ -1,12 +1,15 @@ [metadata] -name = sarafu-token -version = 0.0.1a8 +name = erc20-demurrage-token +version = 0.0.1b1 description = ERC20 token with redistributed continual demurrage author = Louis Holbrook author_email = dev@holbrook.no url = https://gitlab.com/grassrootseconomics/sarafu-token keywords = ethereum + blockchain + cryptocurrency + erc20 classifiers = Programming Language :: Python :: 3 Operating System :: OS Independent @@ -24,18 +27,14 @@ licence_files = include_package_data = True python_requires = >= 3.6 packages = - sarafu_token - sarafu_token.runnable -install_requires = - chainlib~=0.0.3a1 - crypto-dev-signer~=0.4.14b3 - + erc20_demurrage_token + erc20_demurrage_token.runnable [options.package_data] * = - data/RedistributedDemurrageToken.bin - data/RedistributedDemurrageToken.json + data/DemurrageToken*.bin + data/DemurrageToken*.json [options.entry_points] console_scripts = - sarafu-token-deploy = sarafu_token.runnable.deploy:main + erc20-demurrage-token-deploy = erc20_demurrage_token.runnable.deploy:main diff --git a/python/test_requirements.txt b/python/test_requirements.txt @@ -1,3 +1,3 @@ -web3==5.12.2 +#web3==5.12.2 eth_tester==0.5.0b3 py-evm==0.3.0a20 diff --git a/python/tests/base.py b/python/tests/base.py @@ -0,0 +1,78 @@ +# standard imports +import logging + +# 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 + +# 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 = 1 + + + +class TestDemurrage(EthTesterCase): + + def setUp(self): + super(TestDemurrage, self).setUp() + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + self.settings = DemurrageTokenSettings() + self.settings.name = 'Foo Token' + self.settings.symbol = 'FOO' + self.settings.decimals = 6 + self.settings.demurrage_level = TAX_LEVEL * (10 ** 32) + self.settings.period_minutes = PERIOD + self.settings.sink_address = self.accounts[1] + + o = block_latest() + self.start_block = self.rpc.do(o) + + o = block_by_number(self.start_block, include_tx=False) + r = self.rpc.do(o) + logg.debug('r {}'.format(r)) + try: + self.start_time = int(r['timestamp'], 16) + except TypeError: + self.start_time = int(r['timestamp']) + + + 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) + (tx_hash, o) = c.constructor(self.accounts[0], self.settings) + r = self.rpc.do(o) + + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + self.address = r['contract_address'] diff --git a/python/tests/test_basic.py b/python/tests/test_basic.py @@ -5,206 +5,173 @@ import json import logging import datetime -# third-party imports -import web3 -import eth_tester -import eth_abi - -logging.basicConfig(level=logging.DEBUG) -logg = logging.getLogger() - -logging.getLogger('web3').setLevel(logging.WARNING) -logging.getLogger('eth.vm').setLevel(logging.WARNING) - -testdir = os.path.dirname(__file__) - -#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 = 1 - - -class Test(unittest.TestCase): - - contract = None - - def setUp(self): - eth_params = eth_tester.backends.pyevm.main.get_default_genesis_params({ - 'gas_limit': 9000000, - }) - - f = open(os.path.join(testdir, '../../solidity/RedistributedDemurrageToken.bin'), 'r') - self.bytecode = f.read() - f.close() - - f = open(os.path.join(testdir, '../../solidity/RedistributedDemurrageToken.json'), 'r') - self.abi = json.load(f) - f.close() +# external imports +from chainlib.eth.constant import ZERO_ADDRESS +from chainlib.eth.nonce import RPCNonceOracle - backend = eth_tester.PyEVMBackend(eth_params) - self.eth_tester = eth_tester.EthereumTester(backend) - provider = web3.Web3.EthereumTesterProvider(self.eth_tester) - self.w3 = web3.Web3(provider) - self.sink_address = self.w3.eth.accounts[9] +# local imports +from erc20_demurrage_token import DemurrageToken - c = self.w3.eth.contract(abi=self.abi, bytecode=self.bytecode) - tx_hash = c.constructor('Foo Token', 'FOO', 6, TAX_LEVEL * (10 ** 32), PERIOD, self.sink_address).transact({'from': self.w3.eth.accounts[0]}) +# test imports +from tests.base import TestDemurrageDefault - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.contract = self.w3.eth.contract(abi=self.abi, address=r.contractAddress) - - self.start_block = self.w3.eth.blockNumber - b = self.w3.eth.getBlock(self.start_block) - self.start_time = b['timestamp'] +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() +testdir = os.path.dirname(__file__) - def tearDown(self): - pass +class TestBasic(TestDemurrageDefault): + @unittest.skip('foo') def test_hello(self): - self.assertEqual(self.contract.functions.actualPeriod().call(), 1) - self.eth_tester.time_travel(self.start_time + 61) - self.assertEqual(self.contract.functions.actualPeriod().call(), 2) + + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + o = c.actual_period(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + + self.backend.time_travel(self.start_time + 61) + o = c.actual_period(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) def test_apply_demurrage(self): modifier = 10 * (10 ** 37) - #demurrage_modifier = self.contract.functions.demurrageModifier().call() - #demurrage_modifier &= (1 << 128) - 1 - demurrage_amount = self.contract.functions.demurrageAmount().call() - #self.assertEqual(modifier, demurrage_modifier) - self.assertEqual(modifier, demurrage_amount) - - self.eth_tester.time_travel(self.start_time + 59) - #demurrage_modifier = self.contract.functions.demurrageModifier().call() - demurrage_amount = self.contract.functions.demurrageAmount().call() - #demurrage_modifier &= (1 << 128) - 1 - #self.assertEqual(modifier, demurrage_modifier) - self.assertEqual(modifier, demurrage_amount) - - self.eth_tester.time_travel(self.start_time + 61) - tx_hash = self.contract.functions.applyDemurrage().transact() - r = self.w3.eth.getTransactionReceipt(tx_hash) - - #demurrage_modifier = self.contract.functions.demurrageModifier().call() - demurrage_amount = self.contract.functions.demurrageAmount().call() - #demurrage_modifier &= (1 << 128) - 1 - #self.assertEqual(int(98 * (10 ** 36)), demurrage_modifier) - self.assertEqual(int(98 * (10 ** 36)), demurrage_amount) - - - def test_mint(self): - tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1024).transact() - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - - balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() - self.assertEqual(balance, 1024) - tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 976).transact() - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() - self.assertEqual(balance, 2000) - - self.eth_tester.time_travel(self.start_time + 61) - balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() - self.assertEqual(balance, int(2000 * 0.98)) - - - def test_minter_control(self): - with self.assertRaises(eth_tester.exceptions.TransactionFailed): - tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[2], 1024).transact({'from': self.w3.eth.accounts[1]}) - - with self.assertRaises(eth_tester.exceptions.TransactionFailed): - tx_hash = self.contract.functions.addMinter(self.w3.eth.accounts[1]).transact({'from': self.w3.eth.accounts[1]}) - - tx_hash = self.contract.functions.addMinter(self.w3.eth.accounts[1]).transact({'from': self.w3.eth.accounts[0]}) - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - - with self.assertRaises(eth_tester.exceptions.TransactionFailed): - tx_hash = self.contract.functions.addMinter(self.w3.eth.accounts[2]).transact({'from': self.w3.eth.accounts[1]}) - - tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[2], 1024).transact({'from': self.w3.eth.accounts[1]}) - - with self.assertRaises(eth_tester.exceptions.TransactionFailed): - tx_hash = self.contract.functions.addMinter(self.w3.eth.accounts[1]).transact({'from': self.w3.eth.accounts[2]}) - - tx_hash = self.contract.functions.removeMinter(self.w3.eth.accounts[1]).transact({'from': self.w3.eth.accounts[1]}) - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - - with self.assertRaises(eth_tester.exceptions.TransactionFailed): - tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[2], 1024).transact({'from': self.w3.eth.accounts[1]}) - - - def test_base_amount(self): - tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1000).transact() - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - - self.eth_tester.time_travel(self.start_time + 61) - - self.contract.functions.applyDemurrage().transact() - #demurrage_modifier = self.contract.functions.demurrageModifier().call() - #demurrage_amount = self.contract.functions.toDemurrageAmount(demurrage_modifier).call() - demurrage_amount = self.contract.functions.demurrageAmount().call() - - a = self.contract.functions.toBaseAmount(1000).call(); - self.assertEqual(a, 1020) - - - def test_transfer(self): - tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1024).transact() - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - - tx_hash = self.contract.functions.transfer(self.w3.eth.accounts[2], 500).transact({'from': self.w3.eth.accounts[1]}) - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - logg.debug('tx {}'.format(r)) - - balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() - self.assertEqual(balance_alice, 524) - - balance_bob = self.contract.functions.balanceOf(self.w3.eth.accounts[2]).call() - self.assertEqual(balance_bob, 500) - - tx_hash = self.contract.functions.transfer(self.w3.eth.accounts[2], 500).transact({'from': self.w3.eth.accounts[1]}) - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - logg.debug('tx {}'.format(r)) - - - def test_transfer_from(self): - tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1024).transact() - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - - tx_hash = self.contract.functions.approve(self.w3.eth.accounts[2], 500).transact({'from': self.w3.eth.accounts[1]}) - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - logg.debug('tx {}'.format(r)) + o = c.demurrage_amount(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + demurrage_amount = c.parse_demurrage_amount(r) + self.assertEqual(modifier, demurrage_amount) - balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() - self.assertEqual(balance_alice, 1024) + self.backend.time_travel(self.start_time + 59) + o = c.demurrage_amount(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + demurrage_amount = c.parse_demurrage_amount(r) + self.assertEqual(modifier, demurrage_amount) - tx_hash = self.contract.functions.transferFrom(self.w3.eth.accounts[1], self.w3.eth.accounts[3], 500).transact({'from': self.w3.eth.accounts[2]}) - r = self.w3.eth.getTransactionReceipt(tx_hash) - self.assertEqual(r.status, 1) - logg.debug('tx {}'.format(r)) + self.backend.time_travel(self.start_time + 61) + (tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + o = c.demurrage_amount(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + demurrage_amount = c.parse_demurrage_amount(r) + modifier = int(98 * (10 ** 36)) + self.assertEqual(modifier, demurrage_amount) - balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() - self.assertEqual(balance_alice, 524) - balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[3]).call() - self.assertEqual(balance_alice, 500) +# def test_mint(self): +# tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1024).transact() +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# +# balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() +# self.assertEqual(balance, 1024) +# +# tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 976).transact() +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# +# balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() +# self.assertEqual(balance, 2000) +# +# self.eth_tester.time_travel(self.start_time + 61) +# balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() +# self.assertEqual(balance, int(2000 * 0.98)) +# +# +# def test_minter_control(self): +# with self.assertRaises(eth_tester.exceptions.TransactionFailed): +# tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[2], 1024).transact({'from': self.w3.eth.accounts[1]}) +# +# with self.assertRaises(eth_tester.exceptions.TransactionFailed): +# tx_hash = self.contract.functions.addMinter(self.w3.eth.accounts[1]).transact({'from': self.w3.eth.accounts[1]}) +# +# tx_hash = self.contract.functions.addMinter(self.w3.eth.accounts[1]).transact({'from': self.w3.eth.accounts[0]}) +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# +# with self.assertRaises(eth_tester.exceptions.TransactionFailed): +# tx_hash = self.contract.functions.addMinter(self.w3.eth.accounts[2]).transact({'from': self.w3.eth.accounts[1]}) +# +# tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[2], 1024).transact({'from': self.w3.eth.accounts[1]}) +# +# with self.assertRaises(eth_tester.exceptions.TransactionFailed): +# tx_hash = self.contract.functions.addMinter(self.w3.eth.accounts[1]).transact({'from': self.w3.eth.accounts[2]}) +# +# tx_hash = self.contract.functions.removeMinter(self.w3.eth.accounts[1]).transact({'from': self.w3.eth.accounts[1]}) +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# +# with self.assertRaises(eth_tester.exceptions.TransactionFailed): +# tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[2], 1024).transact({'from': self.w3.eth.accounts[1]}) +# +# +# def test_base_amount(self): +# tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1000).transact() +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# +# self.eth_tester.time_travel(self.start_time + 61) +# +# self.contract.functions.applyDemurrage().transact() +# #demurrage_modifier = self.contract.functions.demurrageModifier().call() +# #demurrage_amount = self.contract.functions.toDemurrageAmount(demurrage_modifier).call() +# demurrage_amount = self.contract.functions.demurrageAmount().call() +# +# a = self.contract.functions.toBaseAmount(1000).call(); +# self.assertEqual(a, 1020) +# +# +# def test_transfer(self): +# tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1024).transact() +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# +# tx_hash = self.contract.functions.transfer(self.w3.eth.accounts[2], 500).transact({'from': self.w3.eth.accounts[1]}) +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# logg.debug('tx {}'.format(r)) +# +# balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() +# self.assertEqual(balance_alice, 524) +# +# balance_bob = self.contract.functions.balanceOf(self.w3.eth.accounts[2]).call() +# self.assertEqual(balance_bob, 500) +# +# tx_hash = self.contract.functions.transfer(self.w3.eth.accounts[2], 500).transact({'from': self.w3.eth.accounts[1]}) +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# logg.debug('tx {}'.format(r)) +# +# +# def test_transfer_from(self): +# tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1024).transact() +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# +# tx_hash = self.contract.functions.approve(self.w3.eth.accounts[2], 500).transact({'from': self.w3.eth.accounts[1]}) +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# logg.debug('tx {}'.format(r)) +# +# balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() +# self.assertEqual(balance_alice, 1024) +# +# tx_hash = self.contract.functions.transferFrom(self.w3.eth.accounts[1], self.w3.eth.accounts[3], 500).transact({'from': self.w3.eth.accounts[2]}) +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# self.assertEqual(r.status, 1) +# logg.debug('tx {}'.format(r)) +# +# balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() +# self.assertEqual(balance_alice, 524) +# +# balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[3]).call() +# self.assertEqual(balance_alice, 500) if __name__ == '__main__': diff --git a/solidity/RedistributedDemurrageToken.sol b/solidity/DemurrageTokenMultiNocap.sol diff --git a/solidity/Makefile b/solidity/Makefile @@ -1,9 +1,9 @@ SOLC = /usr/bin/solc all: - $(SOLC) RedistributedDemurrageToken.sol --abi --evm-version byzantium | awk 'NR>3' > RedistributedDemurrageToken.json - $(SOLC) RedistributedDemurrageToken.sol --bin --evm-version byzantium | awk 'NR>3' > RedistributedDemurrageToken.bin - truncate -s -1 RedistributedDemurrageToken.bin + $(SOLC) DemurrageTokenMultiNocap.sol --abi --evm-version byzantium | awk 'NR>3' > DemurrageTokenMultiNocap.json + $(SOLC) DemurrageTokenMultiNocap.sol --bin --evm-version byzantium | awk 'NR>3' > DemurrageTokenMultiNocap.bin + truncate -s -1 DemurrageTokenMultiNocap.bin test: all python ../python/tests/test_basic.py @@ -11,6 +11,6 @@ test: all python ../python/tests/test_redistribution.py install: all - cp -v RedistributedDemurrageToken.{json,bin} ../python/sarafu_token/data/ + cp -v DemurrageTokenMultiNocap.{json,bin} ../python/sarafu_token/data/ .PHONY: test install