erc20-demurrage-token

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

commit dd878aa5cd74a90965f3a605e7163de7b221ff02
parent 32ae98d581cd68a23229c9a9c640a675f0cff0e7
Author: nolash <dev@holbrook.no>
Date:   Mon,  7 Jun 2021 12:08:04 +0200

Apply demurrage on minutes on periods (SingleCap only)

Diffstat:
Mpython/erc20_demurrage_token/data/DemurrageTokenSingleCap.bin | 4++--
Mpython/erc20_demurrage_token/data/DemurrageTokenSingleCap.json | 2+-
Mpython/examples/sim_noredistribute.py | 1-
Mpython/test.sh | 2+-
Mpython/tests/base.py | 3+--
Mpython/tests/test_basic.py | 44+++++++++++++++++++++++++++++++++++++++++---
Mpython/tests/test_redistribution.py | 464++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mpython/tests/test_redistribution_unit.py | 14++++++++++++++
Rpython/tests/test_pure.py -> python/tests/test_remainder.py | 0
Mpython/tests/test_single.py | 1+
Msolidity/DemurrageTokenSingleCap.sol | 37+++++++++++++++++++++++++------------
11 files changed, 320 insertions(+), 252 deletions(-)

diff --git a/python/erc20_demurrage_token/data/DemurrageTokenSingleCap.bin b/python/erc20_demurrage_token/data/DemurrageTokenSingleCap.bin @@ -1 +1 @@ -60e06040523480156200001157600080fd5b506040516200333838038062003338833981810160405281019062000037919062000470565b33600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555086600590805190602001906200010a92919062000309565b5085600690805190602001906200012392919062000309565b508460ff166007819055504260808181525050603c8362000145919062000746565b60a08181525050620f42406d04ee2d6d415b85acef81000000006200016b919062000746565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506001600260106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508360c0818152505060006200020a6000620f424060006001620002a3640100000000026401000000009004565b905060008190806001815401808255809150506001900390600052602060002001600090919091909150558160098190555082600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560ff16600a6200028f919062000609565b600a8190555050505050505050506200098d565b60008073fffff00000000000000000000000000000000000608c60ff16869060020a0216600102811790506cffffffffffffffffff00000000602060ff16859060020a02166001028117905063ffffffff83166001028117905080915050949350505050565b828054620003179062000828565b90600052602060002090601f0160209004810192826200033b576000855562000387565b82601f106200035657805160ff191683800117855562000387565b8280016001018555821562000387579182015b828111156200038657825182559160200191906001019062000369565b5b5090506200039691906200039a565b5090565b5b80821115620003b55760008160009055506001016200039b565b5090565b6000620003d0620003ca8462000578565b6200054f565b905082815260208101848484011115620003e957600080fd5b620003f6848285620007f2565b509392505050565b6000815190506200040f816200093f565b92915050565b600082601f8301126200042757600080fd5b815162000439848260208601620003b9565b91505092915050565b600081519050620004538162000959565b92915050565b6000815190506200046a8162000973565b92915050565b600080600080600080600060e0888a0312156200048c57600080fd5b600088015167ffffffffffffffff811115620004a757600080fd5b620004b58a828b0162000415565b975050602088015167ffffffffffffffff811115620004d357600080fd5b620004e18a828b0162000415565b9650506040620004f48a828b0162000459565b9550506060620005078a828b0162000442565b94505060806200051a8a828b0162000442565b93505060a06200052d8a828b01620003fe565b92505060c0620005408a828b0162000442565b91505092959891949750929550565b60006200055b6200056e565b90506200056982826200085e565b919050565b6000604051905090565b600067ffffffffffffffff821115620005965762000595620008f2565b5b620005a18262000921565b9050602081019050919050565b6000808291508390505b60018511156200060057808604811115620005d857620005d762000894565b5b6001851615620005e85780820291505b8081029050620005f88562000932565b9450620005b8565b94509492505050565b60006200061682620007db565b91506200062383620007db565b9250620006527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846200065a565b905092915050565b6000826200066c57600190506200073f565b816200067c57600090506200073f565b8160018114620006955760028114620006a057620006d6565b60019150506200073f565b60ff841115620006b557620006b462000894565b5b8360020a915084821115620006cf57620006ce62000894565b5b506200073f565b5060208310610133831016604e8410600b8410161715620007105782820a9050838111156200070a576200070962000894565b5b6200073f565b6200071f8484846001620005ae565b9250905081840481111562000739576200073862000894565b5b81810290505b9392505050565b60006200075382620007db565b91506200076083620007db565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156200079c576200079b62000894565b5b828202905092915050565b6000620007b482620007bb565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101562000812578082015181840152602081019050620007f5565b8381111562000822576000848401525b50505050565b600060028204905060018216806200084157607f821691505b60208210811415620008585762000857620008c3565b5b50919050565b620008698262000921565b810181811067ffffffffffffffff821117156200088b576200088a620008f2565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6000600282049050919050565b6200094a81620007a7565b81146200095657600080fd5b50565b6200096481620007db565b81146200097057600080fd5b50565b6200097e81620007e5565b81146200098a57600080fd5b50565b60805160a05160c05161294a620009ee60003960008181610b5501528181610da6015281816119bf0152611f1e01526000818161103c0152818161196d0152611a5a01526000818161106801528181611a7b0152611ac0015261294a6000f3fe608060405234801561001057600080fd5b5060043610610239576000357c0100000000000000000000000000000000000000000000000000000000900480636ffa8a05116101425780639da7d8ba116100ca578063e3ab207a11610099578063e3ab207a14610700578063e54d63f714610730578063e809529514610760578063eda4e6d61461077e578063f2fde38b1461079c57610239565b80639da7d8ba14610664578063a2119e2f14610694578063a9059cbb146106b2578063b470aade146106e257610239565b80638da5cb5b116101115780638da5cb5b146105bc5780638f1df6bc146105da5780638f770ad0146105f857806395d89b4114610616578063983b2d561461063457610239565b80636ffa8a051461052057806370a0823114610550578063731f237c1461058057806379ba50971461059e57610239565b806331333487116101c557806347a505171161019457806347a50517146104425780634abfbba214610472578063573cc507146104a25780636787a9be146104c05780636a2d094e146104f057610239565b80633133348714610394578063313ce567146103c457806340452d91146103e2578063449a52f81461041257610239565b806318160ddd1161020c57806318160ddd146102da5780631989c6a8146102f8578063229ba1971461031657806323b872dd146103345780633092afd51461036457610239565b806301ffc9a71461023e57806306fdde031461026e578063095ea7b31461028c57806309f28f3c146102bc575b600080fd5b610258600480360381019061025391906121f2565b6107cc565b60405161026591906123c0565b60405180910390f35b610276610977565b60405161028391906123f6565b60405180910390f35b6102a660048036038101906102a1919061218d565b610a05565b6040516102b391906123c0565b60405180910390f35b6102c4610b1f565b6040516102d19190612478565b60405180910390f35b6102e2610b41565b6040516102ef91906124ae565b60405180910390f35b610300610b47565b60405161030d91906124ae565b60405180910390f35b61031e610b53565b60405161032b91906124ae565b60405180910390f35b61034e6004803603810190610349919061213e565b610b77565b60405161035b91906123c0565b60405180910390f35b61037e60048036038101906103799190612115565b610c97565b60405161038b91906123c0565b60405180910390f35b6103ae60048036038101906103a9919061226d565b610d8a565b6040516103bb91906124ae565b60405180910390f35b6103cc610e3b565b6040516103d991906124ae565b60405180910390f35b6103fc60048036038101906103f79190612244565b610e41565b60405161040991906123db565b60405180910390f35b61042c6004803603810190610427919061218d565b610e65565b60405161043991906123c0565b60405180910390f35b61045c60048036038101906104579190612115565b610fef565b60405161046991906124ae565b60405180910390f35b61048c60048036038101906104879190612244565b611038565b60405161049991906124ae565b60405180910390f35b6104aa611098565b6040516104b791906124ae565b60405180910390f35b6104da60048036038101906104d59190612244565b61109e565b6040516104e791906124ae565b60405180910390f35b61050a60048036038101906105059190612244565b61110a565b60405161051791906124ae565b60405180910390f35b61053a600480360381019061053591906121c9565b61112b565b60405161054791906124ae565b60405180910390f35b61056a60048036038101906105659190612115565b61115e565b60405161057791906124ae565b60405180910390f35b61058861123f565b60405161059591906123c0565b60405180910390f35b6105a66113ed565b6040516105b391906123c0565b60405180910390f35b6105c4611594565b6040516105d191906123a5565b60405180910390f35b6105e26115ba565b6040516105ef91906123c0565b60405180910390f35b610600611736565b60405161060d91906124ae565b60405180910390f35b61061e61173c565b60405161062b91906123f6565b60405180910390f35b61064e60048036038101906106499190612115565b6117ca565b60405161065b91906123c0565b60405180910390f35b61067e600480360381019061067991906121c9565b611887565b60405161068b91906124ae565b60405180910390f35b61069c6118b3565b6040516106a99190612478565b60405180910390f35b6106cc60048036038101906106c7919061218d565b6118d5565b6040516106d991906123c0565b60405180910390f35b6106ea61196b565b6040516106f791906124ae565b60405180910390f35b61071a600480360381019061071591906121c9565b61198f565b60405161072791906124ae565b60405180910390f35b61074a6004803603810190610745919061226d565b6119a3565b60405161075791906124ae565b60405180910390f35b610768611a54565b6040516107759190612478565b60405180910390f35b610786611abe565b60405161079391906124ae565b60405180910390f35b6107b660048036038101906107b19190612115565b611ae2565b6040516107c391906123c0565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156108215760019050610972565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156108745760019050610972565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156108c75760019050610972565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561091a5760019050610972565b6337a47be47c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561096d5760019050610972565b600090505b919050565b600580546109849061270d565b80601f01602080910402602001604051908101604052809291908181526020018280546109b09061270d565b80156109fd5780601f106109d2576101008083540402835291602001916109fd565b820191906000526020600020905b8154815290600101906020018083116109e057829003601f168201915b505050505081565b600080610a106115ba565b50610a1a8361109e565b905080600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610aa891906124e5565b925050819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610b0c91906124ae565b60405180910390a3600191505092915050565b600260009054906101000a90046fffffffffffffffffffffffffffffffff1681565b60085481565b60008080549050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000610b846115ba565b50610b8e8461109e565b915081600c60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610c1957600080fd5b610c24868684611b84565b90508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051610c8391906124ae565b60405180910390a380925050509392505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610d2057503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b610d2957600080fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000806000620f424091506d04ee2d6d415b85acef81000000007f0000000000000000000000000000000000000000000000000000000000000000610dcf919061253b565b905060005b84811015610e1657620f42408284610dec919061256c565b610df6919061253b565b83610e0191906125fa565b92508080610e0e9061273f565b915050610dd4565b50620f42408583610e27919061256c565b610e31919061253b565b9250505092915050565b60075481565b60008181548110610e5157600080fd5b906000526020600020016000915090505481565b600080600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610ef4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eeb90612438565b60405180910390fd5b60095460085484610f0591906124e5565b1115610f46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3d90612418565b60405180910390fd5b610f4e6115ba565b508290508260086000828254610f6491906124e5565b92505081905550610f758482611bc5565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f885604051610fd391906124ae565b60405180910390a3610fe3611c8a565b50600191505092915050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60007f000000000000000000000000000000000000000000000000000000000000000082611066919061256c565b7f000000000000000000000000000000000000000000000000000000000000000061109191906124e5565b9050919050565b600a5481565b6000600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16620f42406d04ee2d6d415b85acef8100000000846110ef919061256c565b6110f9919061256c565b611103919061253b565b9050919050565b6000603c824261111a91906125fa565b611124919061253b565b9050919050565b6000608c60ff1673fffff00000000000000000000000000000000000836001900416908060020a82049150509050919050565b60008060008061116d85610fef565b9250600260109054906101000a90046fffffffffffffffffffffffffffffffff16611196611a54565b6111a091906125c6565b6fffffffffffffffffffffffffffffffff1690506111ee600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1682610d8a565b6fffffffffffffffffffffffffffffffff169150620f42406d04ee2d6d415b85acef810000000061121f919061256c565b828461122b919061256c565b611235919061253b565b9350505050919050565b600080600080600061124f611a54565b9350600260109054906101000a90046fffffffffffffffffffffffffffffffff168461127b91906125c6565b92506000836fffffffffffffffffffffffffffffffff1614156112a55760009450505050506113ea565b600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1691506112f482846fffffffffffffffffffffffffffffffff16610d8a565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083600260106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555081836fffffffffffffffffffffffffffffffff16856fffffffffffffffffffffffffffffffff167fa0717e54e02bd9829db5e6e998aec0ae9de796b8d150a3cc46a92ab869697755600260009054906101000a90046fffffffffffffffffffffffffffffffff166040516113d99190612493565b60405180910390a460019450505050505b90565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461144a57600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060008060008060008060006115d0611d72565b975060006001028814156115ef57600098505050505050505050611733565b6115f88861198f565b955060018661160791906124e5565b905061161286611038565b915061161c61123f565b50600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1694506116598261110a565b9250600083111561168e576d04ee2d6d415b85acef810000000061167d86856119a3565b611687919061253b565b93506116ab565b6d04ee2d6d415b85acef8100000000856116a8919061253b565b93505b6116ba60008560085484611ea2565b965060008790806001815401808255809150506001900390600052602060002001600090919091909150556116ee88611f08565b507f55d243082e019fce4009ccea5368b92e436c17586a1e793c7deda16df4e5d6758160405161171e91906124ae565b60405180910390a16001985050505050505050505b90565b60095481565b600680546117499061270d565b80601f01602080910402602001604051908101604052809291908181526020018280546117759061270d565b80156117c25780601f10611797576101008083540402835291602001916117c2565b820191906000526020600020905b8154815290600101906020018083116117a557829003601f168201915b505050505081565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461182657600080fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000602060ff166cffffffffffffffffff00000000836001900416908060020a82049150509050919050565b600260109054906101000a90046fffffffffffffffffffffffffffffffff1681565b60008060006118e26115ba565b506118ec8461109e565b91506118f9338684611b84565b90508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8660405161195891906124ae565b60405180910390a3809250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600063ffffffff8260019004169050919050565b6000806000620f424091506d04ee2d6d415b85acef81000000007f00000000000000000000000000000000000000000000000000000000000000006119e8919061253b565b905060005b84811015611a2f57620f42408284611a05919061256c565b611a0f919061253b565b83611a1a91906124e5565b92508080611a279061273f565b9150506119ed565b50620f42408583611a40919061256c565b611a4a919061253b565b9250505092915050565b600060017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000042611aa591906125fa565b611aaf919061253b565b611ab991906124e5565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b3e57600080fd5b81600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550919050565b600080611b918584611fa4565b50611b9c8484611bc5565b50611ba5611a54565b6fffffffffffffffffffffffffffffffff16905060019150509392505050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000851415611c225760009350505050611c84565b611c2b86610fef565b92508483611c3991906124e5565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b60008060006001600080549050611ca191906125fa565b81548110611cd8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001546001900490506cffffffffffffffffff000000001981169050602060ff166008549060020a02811790508060010260006001600080549050611d2591906125fa565b81548110611d5c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550600191505090565b6000806000806001600080549050611d8a91906125fa565b81548110611dc1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015491503073ffffffffffffffffffffffffffffffffffffffff1663e80952956040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611e3057600080fd5b505afa158015611e44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e68919061221b565b6fffffffffffffffffffffffffffffffff169050611e858261198f565b8111611e9957600060010292505050611e9f565b81925050505b90565b60008073fffff00000000000000000000000000000000000608c60ff16869060020a0216600102811790506cffffffffffffffffff00000000602060ff16859060020a02166001028117905063ffffffff83166001028117905080915050949350505050565b6000806000611f1684611887565b9150620f42407f000000000000000000000000000000000000000000000000000000000000000083611f48919061256c565b611f52919061253b565b9050611f99600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166d04ee2d6d415b85acef810000000083611f94919061253b565b611bc5565b508092505050919050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600085141561200157600093505050506120a6565b61200a86610fef565b92508483101561204f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161204690612458565b60405180910390fd5b848361205b91906125fa565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b6000813590506120bb816128a1565b92915050565b6000813590506120d0816128b8565b92915050565b6000813590506120e5816128cf565b92915050565b6000815190506120fa816128e6565b92915050565b60008135905061210f816128fd565b92915050565b60006020828403121561212757600080fd5b6000612135848285016120ac565b91505092915050565b60008060006060848603121561215357600080fd5b6000612161868287016120ac565b9350506020612172868287016120ac565b925050604061218386828701612100565b9150509250925092565b600080604083850312156121a057600080fd5b60006121ae858286016120ac565b92505060206121bf85828601612100565b9150509250929050565b6000602082840312156121db57600080fd5b60006121e9848285016120c1565b91505092915050565b60006020828403121561220457600080fd5b6000612212848285016120d6565b91505092915050565b60006020828403121561222d57600080fd5b600061223b848285016120eb565b91505092915050565b60006020828403121561225657600080fd5b600061226484828501612100565b91505092915050565b6000806040838503121561228057600080fd5b600061228e85828601612100565b925050602061229f85828601612100565b9150509250929050565b6122b28161262e565b82525050565b6122c181612640565b82525050565b6122d08161264c565b82525050565b60006122e1826124c9565b6122eb81856124d4565b93506122fb8185602086016126da565b61230481612815565b840191505092915050565b600061231c6007836124d4565b915061232782612826565b602082019050919050565b600061233f600a836124d4565b915061234a8261284f565b602082019050919050565b6000612362600d836124d4565b915061236d82612878565b602082019050919050565b61238181612682565b82525050565b612390816126c8565b82525050565b61239f816126be565b82525050565b60006020820190506123ba60008301846122a9565b92915050565b60006020820190506123d560008301846122b8565b92915050565b60006020820190506123f060008301846122c7565b92915050565b6000602082019050818103600083015261241081846122d6565b905092915050565b600060208201905081810360008301526124318161230f565b9050919050565b6000602082019050818103600083015261245181612332565b9050919050565b6000602082019050818103600083015261247181612355565b9050919050565b600060208201905061248d6000830184612378565b92915050565b60006020820190506124a86000830184612387565b92915050565b60006020820190506124c36000830184612396565b92915050565b600081519050919050565b600082825260208201905092915050565b60006124f0826126be565b91506124fb836126be565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156125305761252f612788565b5b828201905092915050565b6000612546826126be565b9150612551836126be565b925082612561576125606127b7565b5b828204905092915050565b6000612577826126be565b9150612582836126be565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156125bb576125ba612788565b5b828202905092915050565b60006125d182612682565b91506125dc83612682565b9250828210156125ef576125ee612788565b5b828203905092915050565b6000612605826126be565b9150612610836126be565b92508282101561262357612622612788565b5b828203905092915050565b60006126398261269e565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006126d382612682565b9050919050565b60005b838110156126f85780820151818401526020810190506126dd565b83811115612707576000848401525b50505050565b6000600282049050600182168061272557607f821691505b60208210811415612739576127386127e6565b5b50919050565b600061274a826126be565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561277d5761277c612788565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f4552525f43415000000000000000000000000000000000000000000000000000600082015250565b7f4552525f41434345535300000000000000000000000000000000000000000000600082015250565b7f4552525f4f5645525350454e4400000000000000000000000000000000000000600082015250565b6128aa8161262e565b81146128b557600080fd5b50565b6128c18161264c565b81146128cc57600080fd5b50565b6128d881612656565b81146128e357600080fd5b50565b6128ef81612682565b81146128fa57600080fd5b50565b612906816126be565b811461291157600080fd5b5056fea2646970667358221220214e3585417a90159f70b8ae75d3438aac8e728c20d1c53f9e6532d9bcd5cc4d64736f6c63430008040033 -\ No newline at end of file +60e06040523480156200001157600080fd5b50604051620032d9380380620032d983398181016040528101906200003791906200043f565b33600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600c6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555086600690805190602001906200010a929190620002d8565b50856007908051906020019062000123929190620002d8565b508460ff166008819055504260038190555060035460808181525050603c836200014e919062000715565b60a08181525050620f42406d04ee2d6d415b85acef810000000062000174919062000715565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508360c081815250506000620001d96000620f42406000600162000272640100000000026401000000009004565b9050600081908060018154018082558091505060019003906000526020600020016000909190919091505581600a8190555082600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560ff16600a6200025e9190620005d8565b600b8190555050505050505050506200095c565b60008073fffff00000000000000000000000000000000000608c60ff16869060020a0216600102811790506cffffffffffffffffff00000000602060ff16859060020a02166001028117905063ffffffff83166001028117905080915050949350505050565b828054620002e690620007f7565b90600052602060002090601f0160209004810192826200030a576000855562000356565b82601f106200032557805160ff191683800117855562000356565b8280016001018555821562000356579182015b828111156200035557825182559160200191906001019062000338565b5b50905062000365919062000369565b5090565b5b80821115620003845760008160009055506001016200036a565b5090565b60006200039f620003998462000547565b6200051e565b905082815260208101848484011115620003b857600080fd5b620003c5848285620007c1565b509392505050565b600081519050620003de816200090e565b92915050565b600082601f830112620003f657600080fd5b81516200040884826020860162000388565b91505092915050565b600081519050620004228162000928565b92915050565b600081519050620004398162000942565b92915050565b600080600080600080600060e0888a0312156200045b57600080fd5b600088015167ffffffffffffffff8111156200047657600080fd5b620004848a828b01620003e4565b975050602088015167ffffffffffffffff811115620004a257600080fd5b620004b08a828b01620003e4565b9650506040620004c38a828b0162000428565b9550506060620004d68a828b0162000411565b9450506080620004e98a828b0162000411565b93505060a0620004fc8a828b01620003cd565b92505060c06200050f8a828b0162000411565b91505092959891949750929550565b60006200052a6200053d565b90506200053882826200082d565b919050565b6000604051905090565b600067ffffffffffffffff821115620005655762000564620008c1565b5b6200057082620008f0565b9050602081019050919050565b6000808291508390505b6001851115620005cf57808604811115620005a757620005a662000863565b5b6001851615620005b75780820291505b8081029050620005c78562000901565b945062000587565b94509492505050565b6000620005e582620007aa565b9150620005f283620007aa565b9250620006217fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000629565b905092915050565b6000826200063b57600190506200070e565b816200064b57600090506200070e565b81600181146200066457600281146200066f57620006a5565b60019150506200070e565b60ff84111562000684576200068362000863565b5b8360020a9150848211156200069e576200069d62000863565b5b506200070e565b5060208310610133831016604e8410600b8410161715620006df5782820a905083811115620006d957620006d862000863565b5b6200070e565b620006ee84848460016200057d565b9250905081840481111562000708576200070762000863565b5b81810290505b9392505050565b60006200072282620007aa565b91506200072f83620007aa565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156200076b576200076a62000863565b5b828202905092915050565b600062000783826200078a565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b83811015620007e1578082015181840152602081019050620007c4565b83811115620007f1576000848401525b50505050565b600060028204905060018216806200081057607f821691505b6020821081141562000827576200082662000892565b5b50919050565b6200083882620008f0565b810181811067ffffffffffffffff821117156200085a5762000859620008c1565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6000600282049050919050565b620009198162000776565b81146200092557600080fd5b50565b6200093381620007aa565b81146200093f57600080fd5b50565b6200094d81620007b4565b81146200095957600080fd5b50565b60805160a05160c05161291c620009bd60003960008181610b9001528181610de1015261195b0152600081816110770152818161190901526119f60152600081816110a30152818161131801528181611a170152611a5c015261291c6000f3fe608060405234801561001057600080fd5b5060043610610244576000357c0100000000000000000000000000000000000000000000000000000000900480636787a9be1161014d57806395d89b41116100d5578063e3ab207a11610099578063e3ab207a1461073b578063e54d63f71461076b578063e80952951461079b578063eda4e6d6146107b9578063f2fde38b146107d757610244565b806395d89b411461066f578063983b2d561461068d5780639da7d8ba146106bd578063a9059cbb146106ed578063b470aade1461071d57610244565b8063731f237c1161011c578063731f237c146105d957806379ba5097146105f75780638da5cb5b146106155780638f1df6bc146106335780638f770ad01461065157610244565b80636787a9be146105195780636a2d094e146105495780636ffa8a051461057957806370a08231146105a957610244565b806331333487116101d057806347a505171161019f57806347a505171461044d5780634abfbba21461047d57806351b4541c146104ad578063573cc507146104dd57806358b2833b146104fb57610244565b8063313334871461039f578063313ce567146103cf57806340452d91146103ed578063449a52f81461041d57610244565b806318160ddd1161021757806318160ddd146102e55780631989c6a814610303578063229ba1971461032157806323b872dd1461033f5780633092afd51461036f57610244565b806301ffc9a71461024957806306fdde0314610279578063095ea7b31461029757806309f28f3c146102c7575b600080fd5b610263600480360381019061025e91906121c7565b610807565b6040516102709190612395565b60405180910390f35b6102816109b2565b60405161028e91906123cb565b60405180910390f35b6102b160048036038101906102ac9190612162565b610a40565b6040516102be9190612395565b60405180910390f35b6102cf610b5a565b6040516102dc919061244d565b60405180910390f35b6102ed610b7c565b6040516102fa9190612483565b60405180910390f35b61030b610b82565b6040516103189190612483565b60405180910390f35b610329610b8e565b6040516103369190612483565b60405180910390f35b61035960048036038101906103549190612113565b610bb2565b6040516103669190612395565b60405180910390f35b610389600480360381019061038491906120ea565b610cd2565b6040516103969190612395565b60405180910390f35b6103b960048036038101906103b49190612242565b610dc5565b6040516103c69190612483565b60405180910390f35b6103d7610e76565b6040516103e49190612483565b60405180910390f35b61040760048036038101906104029190612219565b610e7c565b60405161041491906123b0565b60405180910390f35b61043760048036038101906104329190612162565b610ea0565b6040516104449190612395565b60405180910390f35b610467600480360381019061046291906120ea565b61102a565b6040516104749190612483565b60405180910390f35b61049760048036038101906104929190612219565b611073565b6040516104a49190612483565b60405180910390f35b6104c760048036038101906104c29190612219565b6110d3565b6040516104d49190612483565b60405180910390f35b6104e56110f4565b6040516104f29190612483565b60405180910390f35b6105036110fa565b6040516105109190612483565b60405180910390f35b610533600480360381019061052e9190612219565b611100565b6040516105409190612483565b60405180910390f35b610563600480360381019061055e9190612219565b61116c565b6040516105709190612483565b60405180910390f35b610593600480360381019061058e919061219e565b61118d565b6040516105a09190612483565b60405180910390f35b6105c360048036038101906105be91906120ea565b6111c0565b6040516105d09190612483565b60405180910390f35b6105e1611269565b6040516105ee9190612395565b60405180910390f35b6105ff6113ab565b60405161060c9190612395565b60405180910390f35b61061d611552565b60405161062a919061237a565b60405180910390f35b61063b611578565b6040516106489190612395565b60405180910390f35b6106596116f4565b6040516106669190612483565b60405180910390f35b6106776116fa565b60405161068491906123cb565b60405180910390f35b6106a760048036038101906106a291906120ea565b611788565b6040516106b49190612395565b60405180910390f35b6106d760048036038101906106d2919061219e565b611845565b6040516106e49190612483565b60405180910390f35b61070760048036038101906107029190612162565b611871565b6040516107149190612395565b60405180910390f35b610725611907565b6040516107329190612483565b60405180910390f35b6107556004803603810190610750919061219e565b61192b565b6040516107629190612483565b60405180910390f35b61078560048036038101906107809190612242565b61193f565b6040516107929190612483565b60405180910390f35b6107a36119f0565b6040516107b0919061244d565b60405180910390f35b6107c1611a5a565b6040516107ce9190612483565b60405180910390f35b6107f160048036038101906107ec91906120ea565b611a7e565b6040516107fe9190612395565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561085c57600190506109ad565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156108af57600190506109ad565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561090257600190506109ad565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561095557600190506109ad565b6337a47be47c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156109a857600190506109ad565b600090505b919050565b600680546109bf906126df565b80601f01602080910402602001604051908101604052809291908181526020018280546109eb906126df565b8015610a385780601f10610a0d57610100808354040283529160200191610a38565b820191906000526020600020905b815481529060010190602001808311610a1b57829003601f168201915b505050505081565b600080610a4b611578565b50610a5583611100565b905080600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610ae391906124ba565b925050819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610b479190612483565b60405180910390a3600191505092915050565b600260009054906101000a90046fffffffffffffffffffffffffffffffff1681565b60095481565b60008080549050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000610bbf611578565b50610bc984611100565b915081600d60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610c5457600080fd5b610c5f868684611b20565b90508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051610cbe9190612483565b60405180910390a380925050509392505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610d5b57503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b610d6457600080fd5b6000600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000806000620f424091506d04ee2d6d415b85acef81000000007f0000000000000000000000000000000000000000000000000000000000000000610e0a9190612541565b905060005b84811015610e5157620f42408284610e279190612572565b610e319190612541565b83610e3c91906125cc565b92508080610e4990612711565b915050610e0f565b50620f42408583610e629190612572565b610e6c9190612541565b9250505092915050565b60085481565b60008181548110610e8c57600080fd5b906000526020600020016000915090505481565b600080600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610f2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f269061240d565b60405180910390fd5b600a5460095484610f4091906124ba565b1115610f81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f78906123ed565b60405180910390fd5b610f89611578565b508290508260096000828254610f9f91906124ba565b92505081905550610fb08482611b61565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f88560405161100e9190612483565b60405180910390a361101e611c26565b50600191505092915050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60007f0000000000000000000000000000000000000000000000000000000000000000826110a19190612572565b7f00000000000000000000000000000000000000000000000000000000000000006110cc91906124ba565b9050919050565b6000603c82426110e391906125cc565b6110ed9190612541565b9050919050565b600b5481565b60035481565b6000600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16620f42406d04ee2d6d415b85acef8100000000846111519190612572565b61115b9190612572565b6111659190612541565b9050919050565b6000603c824261117c91906125cc565b6111869190612541565b9050919050565b6000608c60ff1673fffff00000000000000000000000000000000000836001900416908060020a82049150509050919050565b6000806000806111cf8561102a565b92506111dc6003546110d3565b9050611218600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1682610dc5565b6fffffffffffffffffffffffffffffffff169150620f42406d04ee2d6d415b85acef81000000006112499190612572565b82846112559190612572565b61125f9190612541565b9350505050919050565b600080600080600061127c6003546110d3565b925060008314156112945760009450505050506113a8565b600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1691506112d18284610dc5565b600260006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550603c836113169190612572565b7f000000000000000000000000000000000000000000000000000000000000000061134191906124ba565b6003819055508183427fa0717e54e02bd9829db5e6e998aec0ae9de796b8d150a3cc46a92ab869697755600260009054906101000a90046fffffffffffffffffffffffffffffffff166040516113979190612468565b60405180910390a460019450505050505b90565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461140857600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35090565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600080600080600061158e611d1e565b975060006001028814156115ad576000985050505050505050506116f1565b6115b68861192b565b95506001866115c591906124ba565b90506115d086611073565b91506115da611269565b50600260009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1694506116178261116c565b9250600083111561164c576d04ee2d6d415b85acef810000000061163b868561193f565b6116459190612541565b9350611669565b6d04ee2d6d415b85acef8100000000856116669190612541565b93505b61167860008560095484611e4e565b965060008790806001815401808255809150506001900390600052602060002001600090919091909150556116ac88611eb4565b507f55d243082e019fce4009ccea5368b92e436c17586a1e793c7deda16df4e5d675816040516116dc9190612483565b60405180910390a16001985050505050505050505b90565b600a5481565b60078054611707906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054611733906126df565b80156117805780601f1061175557610100808354040283529160200191611780565b820191906000526020600020905b81548152906001019060200180831161176357829003601f168201915b505050505081565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117e457600080fd5b6001600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000602060ff166cffffffffffffffffff00000000836001900416908060020a82049150509050919050565b600080600061187e611578565b5061188884611100565b9150611895338684611b20565b90508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040516118f49190612483565b60405180910390a3809250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600063ffffffff8260019004169050919050565b6000806000620f424091506d04ee2d6d415b85acef81000000007f00000000000000000000000000000000000000000000000000000000000000006119849190612541565b905060005b848110156119cb57620f424082846119a19190612572565b6119ab9190612541565b836119b691906124ba565b925080806119c390612711565b915050611989565b50620f424085836119dc9190612572565b6119e69190612541565b9250505092915050565b600060017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000042611a4191906125cc565b611a4b9190612541565b611a5591906124ba565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ada57600080fd5b81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550919050565b600080611b2d8584611f79565b50611b388484611b61565b50611b416119f0565b6fffffffffffffffffffffffffffffffff16905060019150509392505050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000851415611bbe5760009350505050611c20565b611bc78661102a565b92508483611bd591906124ba565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b6000806000611c38600954600161193f565b905060006001600080549050611c4e91906125cc565b81548110611c85577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001546001900491506cffffffffffffffffff000000001982169150602060ff16819060020a02821791508160010260006001600080549050611cd091906125cc565b81548110611d07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555060019250505090565b6000806000806001600080549050611d3691906125cc565b81548110611d6d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015491503073ffffffffffffffffffffffffffffffffffffffff1663e80952956040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b158015611ddc57600080fd5b505afa158015611df0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1491906121f0565b6fffffffffffffffffffffffffffffffff169050611e318261192b565b8111611e4557600060010292505050611e4b565b81925050505b90565b60008073fffff00000000000000000000000000000000000608c60ff16869060020a0216600102811790506cffffffffffffffffff00000000602060ff16859060020a02166001028117905063ffffffff83166001028117905080915050949350505050565b6000806000611ec284611845565b9150620f4240600260009054906101000a90046fffffffffffffffffffffffffffffffff16611ef19190612510565b6fffffffffffffffffffffffffffffffff166d04ee2d6d415b85acef8100000000611f1c91906125cc565b82611f279190612572565b9050611f6e600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166d04ee2d6d415b85acef810000000083611f699190612541565b611b61565b508092505050919050565b600080600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000851415611fd6576000935050505061207b565b611fdf8661102a565b925084831015612024576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201b9061242d565b60405180910390fd5b848361203091906125cc565b600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600193505050505b92915050565b60008135905061209081612873565b92915050565b6000813590506120a58161288a565b92915050565b6000813590506120ba816128a1565b92915050565b6000815190506120cf816128b8565b92915050565b6000813590506120e4816128cf565b92915050565b6000602082840312156120fc57600080fd5b600061210a84828501612081565b91505092915050565b60008060006060848603121561212857600080fd5b600061213686828701612081565b935050602061214786828701612081565b9250506040612158868287016120d5565b9150509250925092565b6000806040838503121561217557600080fd5b600061218385828601612081565b9250506020612194858286016120d5565b9150509250929050565b6000602082840312156121b057600080fd5b60006121be84828501612096565b91505092915050565b6000602082840312156121d957600080fd5b60006121e7848285016120ab565b91505092915050565b60006020828403121561220257600080fd5b6000612210848285016120c0565b91505092915050565b60006020828403121561222b57600080fd5b6000612239848285016120d5565b91505092915050565b6000806040838503121561225557600080fd5b6000612263858286016120d5565b9250506020612274858286016120d5565b9150509250929050565b61228781612600565b82525050565b61229681612612565b82525050565b6122a58161261e565b82525050565b60006122b68261249e565b6122c081856124a9565b93506122d08185602086016126ac565b6122d9816127e7565b840191505092915050565b60006122f16007836124a9565b91506122fc826127f8565b602082019050919050565b6000612314600a836124a9565b915061231f82612821565b602082019050919050565b6000612337600d836124a9565b91506123428261284a565b602082019050919050565b61235681612654565b82525050565b6123658161269a565b82525050565b61237481612690565b82525050565b600060208201905061238f600083018461227e565b92915050565b60006020820190506123aa600083018461228d565b92915050565b60006020820190506123c5600083018461229c565b92915050565b600060208201905081810360008301526123e581846122ab565b905092915050565b60006020820190508181036000830152612406816122e4565b9050919050565b6000602082019050818103600083015261242681612307565b9050919050565b600060208201905081810360008301526124468161232a565b9050919050565b6000602082019050612462600083018461234d565b92915050565b600060208201905061247d600083018461235c565b92915050565b6000602082019050612498600083018461236b565b92915050565b600081519050919050565b600082825260208201905092915050565b60006124c582612690565b91506124d083612690565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156125055761250461275a565b5b828201905092915050565b600061251b82612654565b915061252683612654565b92508261253657612535612789565b5b828204905092915050565b600061254c82612690565b915061255783612690565b92508261256757612566612789565b5b828204905092915050565b600061257d82612690565b915061258883612690565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156125c1576125c061275a565b5b828202905092915050565b60006125d782612690565b91506125e283612690565b9250828210156125f5576125f461275a565b5b828203905092915050565b600061260b82612670565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006126a582612654565b9050919050565b60005b838110156126ca5780820151818401526020810190506126af565b838111156126d9576000848401525b50505050565b600060028204905060018216806126f757607f821691505b6020821081141561270b5761270a6127b8565b5b50919050565b600061271c82612690565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274f5761274e61275a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f4552525f43415000000000000000000000000000000000000000000000000000600082015250565b7f4552525f41434345535300000000000000000000000000000000000000000000600082015250565b7f4552525f4f5645525350454e4400000000000000000000000000000000000000600082015250565b61287c81612600565b811461288757600080fd5b50565b6128938161261e565b811461289e57600080fd5b50565b6128aa81612628565b81146128b557600080fd5b50565b6128c181612654565b81146128cc57600080fd5b50565b6128d881612690565b81146128e357600080fd5b5056fea2646970667358221220df21498e73b8152705b34212597fc6d22bec4cff54111426c874c43e5fd2df6464736f6c63430008040033 +\ No newline at end of file diff --git a/python/erc20_demurrage_token/data/DemurrageTokenSingleCap.json b/python/erc20_demurrage_token/data/DemurrageTokenSingleCap.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"uint256","name":"_taxLevelMinute","type":"uint256"},{"internalType":"uint256","name":"_periodMinutes","type":"uint256"},{"internalType":"address","name":"_defaultSinkAddress","type":"address"},{"internalType":"uint256","name":"_supplyCap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_foo","type":"bytes32"}],"name":"Debug","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_periodCount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newAmount","type":"uint256"}],"name":"Decayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"},{"indexed":true,"internalType":"address","name":"_beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_period","type":"uint256"}],"name":"Period","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Redistribution","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"actualPeriod","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"addMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"applyDemurrage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"baseBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"changePeriod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"decayBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"demurrageAmount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_target","type":"uint256"}],"name":"demurrageCycles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"demurragePeriod","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_periodCount","type":"uint256"}],"name":"getPeriodTimeDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"growBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumParticipantSpend","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redistributionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redistributions","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"removeMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"toBaseAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"redistribution","type":"bytes32"}],"name":"toRedistributionDemurrageModifier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"redistribution","type":"bytes32"}],"name":"toRedistributionPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"redistribution","type":"bytes32"}],"name":"toRedistributionSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"uint256","name":"_taxLevelMinute","type":"uint256"},{"internalType":"uint256","name":"_periodMinutes","type":"uint256"},{"internalType":"address","name":"_defaultSinkAddress","type":"address"},{"internalType":"uint256","name":"_supplyCap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_foo","type":"bytes32"}],"name":"Debug","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_periodCount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newAmount","type":"uint256"}],"name":"Decayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"},{"indexed":true,"internalType":"address","name":"_beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_period","type":"uint256"}],"name":"Period","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"},{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Redistribution","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"actualPeriod","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"addMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"applyDemurrage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"baseBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"changePeriod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"decayBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"demurrageAmount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_target","type":"uint256"}],"name":"demurrageCycles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"demurrageTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastTimestamp","type":"uint256"}],"name":"getMinutesDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_periodCount","type":"uint256"}],"name":"getPeriodTimeDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"growBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumParticipantSpend","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redistributionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redistributions","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"removeMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"toBaseAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"redistribution","type":"bytes32"}],"name":"toRedistributionDemurrageModifier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"redistribution","type":"bytes32"}],"name":"toRedistributionPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"redistribution","type":"bytes32"}],"name":"toRedistributionSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/python/examples/sim_noredistribute.py b/python/examples/sim_noredistribute.py @@ -19,7 +19,6 @@ settings.demurrage_level = int(decay_per_minute*(10**38)) settings.period_minutes = 1 # 1 week in minutes chain = 'evm:foochain:42' cap = (10 ** 6) * (10 ** 12) -#cap = 0 # instantiate simulation sim = DemurrageTokenSimulation(chain, settings, redistribute=False, cap=cap, actors=10) diff --git a/python/test.sh b/python/test.sh @@ -23,7 +23,7 @@ done modes=(MultiCap MultiNocap) for m in ${modes[@]}; do - ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_pure.py + ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_remainder.py ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_redistribution.py done diff --git a/python/tests/base.py b/python/tests/base.py @@ -28,8 +28,7 @@ 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 - +PERIOD = 10 class TestDemurrage(EthTesterCase): diff --git a/python/tests/test_basic.py b/python/tests/test_basic.py @@ -9,6 +9,10 @@ import datetime from chainlib.eth.constant import ZERO_ADDRESS from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.tx import receipt +from chainlib.eth.block import ( + block_latest, + block_by_number, + ) # local imports from erc20_demurrage_token import DemurrageToken @@ -46,21 +50,55 @@ class TestBasic(TestDemurrageDefault): demurrage_amount = c.parse_demurrage_amount(r) self.assertEqual(modifier, demurrage_amount) - self.backend.time_travel(self.start_time + self.period_seconds - 1) + o = block_latest() + r = self.rpc.do(o) + o = block_by_number(r) + b = self.rpc.do(o) + logg.debug('block {} start {}'.format(b['timestamp'], self.start_time)) + + self.backend.time_travel(self.start_time + 2) + (tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + 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) - self.backend.time_travel(self.start_time + self.period_seconds + 1) + 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 = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) 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)) + modifier_base = 1000000 - self.tax_level + logg.debug('modifier base {}'.format(modifier_base)) + modifier = int(modifier_base * (10 ** 32)) # 38 decimal places minus 6 (1000000) self.assertEqual(modifier, demurrage_amount) + self.backend.time_travel(self.start_time + 601) + (tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + o = c.demurrage_amount(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + demurrage_amount = c.parse_demurrage_amount(r) + modifier_base = ((1000000 - self.tax_level) / 1000000) ** 10 + modifier = int(modifier_base * (10 ** 12)) + + rounding_tolerance_nano = 4000000 # 0.000004% precision + demurrage_amount_truncate = int(demurrage_amount / (10 ** 26)) # equals 12 decimal places + self.assertGreaterEqual(modifier, demurrage_amount_truncate - rounding_tolerance_nano) + self.assertLessEqual(modifier, demurrage_amount_truncate) + def test_mint(self): nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) diff --git a/python/tests/test_redistribution.py b/python/tests/test_redistribution.py @@ -31,7 +31,6 @@ testdir = os.path.dirname(__file__) class TestRedistribution(TestDemurrageDefault): - @unittest.expectedFailure def test_whole_is_parts(self): nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) @@ -84,239 +83,244 @@ class TestRedistribution(TestDemurrageDefault): balance += balance_item logg.debug('balance {} {} total {}'.format(i, balance_item, balance)) - self.assertEqual(balance, 200000000) - - - def test_debug_periods(self): - 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) - pactual = c.parse_actual_period(r) - - o = c.period_start(self.address, sender_address=self.accounts[0]) - r = self.rpc.do(o) - pstart = c.parse_actual_period(r) - - o = c.period_duration(self.address, sender_address=self.accounts[0]) - r = self.rpc.do(o) - pduration = c.parse_actual_period(r) - - o = block_latest() - blocknumber = self.rpc.do(o) - - logg.debug('actual {} start {} duration {} blocknumber {}'.format(pactual, pstart, pduration, blocknumber)) - - - # TODO: check receipt log outputs - def test_redistribution_storage(self): - nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) - r = self.rpc.do(o) - self.assertEqual(strip_0x(r), '000000000000000000000000f424000000000000000000000000000000000001') - - (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], 1000000) - r = self.rpc.do(o) - - (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[2], 1000000) - r = self.rpc.do(o) - - external_address = to_checksum_address('0x' + os.urandom(20).hex()) - - nonce_oracle = RPCNonceOracle(self.accounts[2], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.transfer(self.address, self.accounts[2], external_address, 1000000) - r = self.rpc.do(o) - - nonce_oracle = RPCNonceOracle(self.accounts[1], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.transfer(self.address, self.accounts[1], external_address, 999999) - r = self.rpc.do(o) - - self.backend.time_travel(self.start_time + self.period_seconds + 1) - - o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) - r = self.rpc.do(o) - self.assertEqual(strip_0x(r), '000000000000000000000000f42400000000010000000000001e848000000001') - - o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) - r = self.rpc.do(o) - self.assertEqual(strip_0x(r), '000000000000000000000000f42400000000010000000000001e848000000001') - - - nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[0], 1000000) - r = self.rpc.do(o) - - o = c.redistributions(self.address, 1, sender_address=self.accounts[0]) - r = self.rpc.do(o) - self.assertEqual(strip_0x(r), '000000000000000000000000ef4200000000000000000000002dc6c000000002') - - - def test_redistribution_balance_on_zero_participants(self): - supply = self.default_supply - - nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], supply) - r = self.rpc.do(o) - - self.backend.time_travel(self.start_time + self.period_seconds + 1) - (tx_hash, o) = c.apply_demurrage(self.address, self.accounts[0]) - self.rpc.do(o) - o = receipt(tx_hash) - rcpt = self.rpc.do(o) - self.assertEqual(rcpt['status'], 1) - - (tx_hash, o) = c.change_period(self.address, self.accounts[0]) - self.rpc.do(o) - o = receipt(tx_hash) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - o = c.total_supply(self.address, sender_address=self.accounts[0]) - r = self.rpc.do(o) - total_supply = c.parse_total_supply(r) - sink_increment = int(total_supply * (self.tax_level / 1000000)) - self.assertEqual(supply, total_supply) - - for l in rcpt['logs']: - if l['topics'][0] == '0xa0717e54e02bd9829db5e6e998aec0ae9de796b8d150a3cc46a92ab869697755': # event Decayed(uint256,uint256,uint256,uint256) - period = int.from_bytes(bytes.fromhex(strip_0x(l['topics'][1])), 'big') - self.assertEqual(period, 2) - b = bytes.fromhex(strip_0x(l['data'])) - remainder = int.from_bytes(b, 'big') - self.assertEqual(remainder, int((1000000 - self.tax_level) * (10 ** 32))) - o = c.balance_of(self.address, self.sink_address, sender_address=self.accounts[0]) r = self.rpc.do(o) - sink_balance = c.parse_balance_of(r) - - self.assertEqual(sink_balance, int(sink_increment * 0.98)) - self.assertEqual(sink_balance, int(sink_increment * (1000000 - self.tax_level) / 1000000)) - - o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) - r = self.rpc.do(o) - balance = c.parse_balance_of(r) - self.assertEqual(balance, supply - sink_increment) + balance_item = c.parse_balance_of(r) + balance += balance_item + self.assertEqual(balance, 200000000) + - def test_redistribution_two_of_ten(self): - mint_amount = 100000000 - nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - z = 0 - for i in range(10): - (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[i], mint_amount) - self.rpc.do(o) - z += mint_amount - - o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) - r = self.rpc.do(o) - initial_balance = c.parse_balance_of(r) - - spend_amount = 1000000 - external_address = to_checksum_address('0x' + os.urandom(20).hex()) - - nonce_oracle = RPCNonceOracle(self.accounts[1], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.transfer(self.address, self.accounts[1], external_address, spend_amount) - self.rpc.do(o) - o = receipt(tx_hash) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - nonce_oracle = RPCNonceOracle(self.accounts[2], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.transfer(self.address, self.accounts[2], external_address, spend_amount) - self.rpc.do(o) - o = receipt(tx_hash) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - # No cheating! - nonce_oracle = RPCNonceOracle(self.accounts[3], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.transfer(self.address, self.accounts[3], self.accounts[3], spend_amount) - self.rpc.do(o) - o = receipt(tx_hash) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - # No cheapskating! - nonce_oracle = RPCNonceOracle(self.accounts[4], self.rpc) - c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash, o) = c.transfer(self.address, self.accounts[4], external_address, spend_amount-1) - self.rpc.do(o) - o = receipt(tx_hash) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - - self.backend.time_travel(self.start_time + self.period_seconds + 1) - - (tx_hash, o) = c.apply_demurrage(self.address, self.accounts[4]) - self.rpc.do(o) - - (tx_hash, o) = c.change_period(self.address, self.accounts[4]) - self.rpc.do(o) - - o = c.balance_of(self.address, self.accounts[3], sender_address=self.accounts[0]) - r = self.rpc.do(o) - bummer_balance = c.parse_balance_of(r) - - self.assertEqual(bummer_balance, mint_amount - (mint_amount * (self.tax_level / 1000000))) - logg.debug('bal {} '.format(bummer_balance)) - - o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) - r = self.rpc.do(o) - bummer_balance = c.parse_balance_of(r) - spender_balance = mint_amount - spend_amount - spender_decayed_balance = int(spender_balance - (spender_balance * (self.tax_level / 1000000))) - self.assertEqual(bummer_balance, spender_decayed_balance) - logg.debug('bal {} '.format(bummer_balance)) - - (tx_hash, o) = c.apply_redistribution_on_account(self.address, self.accounts[4], self.accounts[1]) - self.rpc.do(o) - o = receipt(tx_hash) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - (tx_hash, o) = c.apply_redistribution_on_account(self.address, self.accounts[4], self.accounts[2]) - self.rpc.do(o) - o = receipt(tx_hash) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) - r = self.rpc.do(o) - redistribution_data = c.parse_redistributions(r) - logg.debug('redist data {}'.format(redistribution_data)) - - o = c.account_period(self.address, self.accounts[1], sender_address=self.accounts[0]) - r = self.rpc.do(o) - account_period_data = c.parse_account_period(r) - logg.debug('account period {}'.format(account_period_data)) - - o = c.actual_period(self.address, sender_address=self.accounts[0]) - r = self.rpc.do(o) - actual_period = c.parse_actual_period(r) - logg.debug('period {}'.format(actual_period)) - - redistribution = int((z / 2) * (self.tax_level / 1000000)) - spender_new_base_balance = ((mint_amount - spend_amount) + redistribution) - spender_new_decayed_balance = int(spender_new_base_balance - (spender_new_base_balance * (self.tax_level / 1000000))) - - o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) - r = self.rpc.do(o) - spender_actual_balance = c.parse_balance_of(r) - logg.debug('rrr {} {}'.format(redistribution, spender_new_decayed_balance)) - - self.assertEqual(spender_actual_balance, spender_new_decayed_balance) - +# def test_debug_periods(self): +# 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) +# pactual = c.parse_actual_period(r) +# +# o = c.period_start(self.address, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# pstart = c.parse_actual_period(r) +# +# o = c.period_duration(self.address, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# pduration = c.parse_actual_period(r) +# +# o = block_latest() +# blocknumber = self.rpc.do(o) +# +# logg.debug('actual {} start {} duration {} blocknumber {}'.format(pactual, pstart, pduration, blocknumber)) +# +# +# # TODO: check receipt log outputs +# def test_redistribution_storage(self): +# nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# self.assertEqual(strip_0x(r), '000000000000000000000000f424000000000000000000000000000000000001') +# +# (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], 1000000) +# r = self.rpc.do(o) +# +# (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[2], 1000000) +# r = self.rpc.do(o) +# +# external_address = to_checksum_address('0x' + os.urandom(20).hex()) +# +# nonce_oracle = RPCNonceOracle(self.accounts[2], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# (tx_hash, o) = c.transfer(self.address, self.accounts[2], external_address, 1000000) +# r = self.rpc.do(o) +# +# nonce_oracle = RPCNonceOracle(self.accounts[1], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# (tx_hash, o) = c.transfer(self.address, self.accounts[1], external_address, 999999) +# r = self.rpc.do(o) +# +# self.backend.time_travel(self.start_time + self.period_seconds + 1) +# +# o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# self.assertEqual(strip_0x(r), '000000000000000000000000f42400000000010000000000001e848000000001') +# +# o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# self.assertEqual(strip_0x(r), '000000000000000000000000f42400000000010000000000001e848000000001') +# +# +# nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[0], 1000000) +# r = self.rpc.do(o) +# +# o = c.redistributions(self.address, 1, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# self.assertEqual(strip_0x(r), '000000000000000000000000ef4200000000000000000000002dc6c000000002') +# +# +# def test_redistribution_balance_on_zero_participants(self): +# supply = self.default_supply +# +# nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], supply) +# r = self.rpc.do(o) +# +# self.backend.time_travel(self.start_time + self.period_seconds + 1) +# (tx_hash, o) = c.apply_demurrage(self.address, self.accounts[0]) +# self.rpc.do(o) +# o = receipt(tx_hash) +# rcpt = self.rpc.do(o) +# self.assertEqual(rcpt['status'], 1) +# +# (tx_hash, o) = c.change_period(self.address, self.accounts[0]) +# self.rpc.do(o) +# o = receipt(tx_hash) +# r = self.rpc.do(o) +# self.assertEqual(r['status'], 1) +# +# o = c.total_supply(self.address, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# total_supply = c.parse_total_supply(r) +# sink_increment = int(total_supply * (self.tax_level / 1000000)) +# self.assertEqual(supply, total_supply) +# +# for l in rcpt['logs']: +# if l['topics'][0] == '0xa0717e54e02bd9829db5e6e998aec0ae9de796b8d150a3cc46a92ab869697755': # event Decayed(uint256,uint256,uint256,uint256) +# period = int.from_bytes(bytes.fromhex(strip_0x(l['topics'][1])), 'big') +# self.assertEqual(period, 2) +# b = bytes.fromhex(strip_0x(l['data'])) +# remainder = int.from_bytes(b, 'big') +# self.assertEqual(remainder, int((1000000 - self.tax_level) * (10 ** 32))) +# +# o = c.balance_of(self.address, self.sink_address, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# sink_balance = c.parse_balance_of(r) +# +# self.assertEqual(sink_balance, int(sink_increment * 0.98)) +# self.assertEqual(sink_balance, int(sink_increment * (1000000 - self.tax_level) / 1000000)) +# +# o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# balance = c.parse_balance_of(r) +# self.assertEqual(balance, supply - sink_increment) +# +# +# def test_redistribution_two_of_ten(self): +# mint_amount = 100000000 +# nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# z = 0 +# for i in range(10): +# (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[i], mint_amount) +# self.rpc.do(o) +# z += mint_amount +# +# o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# initial_balance = c.parse_balance_of(r) +# +# spend_amount = 1000000 +# external_address = to_checksum_address('0x' + os.urandom(20).hex()) +# +# nonce_oracle = RPCNonceOracle(self.accounts[1], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# (tx_hash, o) = c.transfer(self.address, self.accounts[1], external_address, spend_amount) +# self.rpc.do(o) +# o = receipt(tx_hash) +# r = self.rpc.do(o) +# self.assertEqual(r['status'], 1) +# +# nonce_oracle = RPCNonceOracle(self.accounts[2], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# (tx_hash, o) = c.transfer(self.address, self.accounts[2], external_address, spend_amount) +# self.rpc.do(o) +# o = receipt(tx_hash) +# r = self.rpc.do(o) +# self.assertEqual(r['status'], 1) +# +# # No cheating! +# nonce_oracle = RPCNonceOracle(self.accounts[3], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# (tx_hash, o) = c.transfer(self.address, self.accounts[3], self.accounts[3], spend_amount) +# self.rpc.do(o) +# o = receipt(tx_hash) +# r = self.rpc.do(o) +# self.assertEqual(r['status'], 1) +# +# # No cheapskating! +# nonce_oracle = RPCNonceOracle(self.accounts[4], self.rpc) +# c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) +# (tx_hash, o) = c.transfer(self.address, self.accounts[4], external_address, spend_amount-1) +# self.rpc.do(o) +# o = receipt(tx_hash) +# r = self.rpc.do(o) +# self.assertEqual(r['status'], 1) +# +# +# self.backend.time_travel(self.start_time + self.period_seconds + 1) +# +# (tx_hash, o) = c.apply_demurrage(self.address, self.accounts[4]) +# self.rpc.do(o) +# +# (tx_hash, o) = c.change_period(self.address, self.accounts[4]) +# self.rpc.do(o) +# +# o = c.balance_of(self.address, self.accounts[3], sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# bummer_balance = c.parse_balance_of(r) +# +# self.assertEqual(bummer_balance, mint_amount - (mint_amount * (self.tax_level / 1000000))) +# logg.debug('bal {} '.format(bummer_balance)) +# +# o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# bummer_balance = c.parse_balance_of(r) +# spender_balance = mint_amount - spend_amount +# spender_decayed_balance = int(spender_balance - (spender_balance * (self.tax_level / 1000000))) +# self.assertEqual(bummer_balance, spender_decayed_balance) +# logg.debug('bal {} '.format(bummer_balance)) +# +# (tx_hash, o) = c.apply_redistribution_on_account(self.address, self.accounts[4], self.accounts[1]) +# self.rpc.do(o) +# o = receipt(tx_hash) +# r = self.rpc.do(o) +# self.assertEqual(r['status'], 1) +# +# (tx_hash, o) = c.apply_redistribution_on_account(self.address, self.accounts[4], self.accounts[2]) +# self.rpc.do(o) +# o = receipt(tx_hash) +# r = self.rpc.do(o) +# self.assertEqual(r['status'], 1) +# +# o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# redistribution_data = c.parse_redistributions(r) +# logg.debug('redist data {}'.format(redistribution_data)) +# +# o = c.account_period(self.address, self.accounts[1], sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# account_period_data = c.parse_account_period(r) +# logg.debug('account period {}'.format(account_period_data)) +# +# o = c.actual_period(self.address, sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# actual_period = c.parse_actual_period(r) +# logg.debug('period {}'.format(actual_period)) +# +# redistribution = int((z / 2) * (self.tax_level / 1000000)) +# spender_new_base_balance = ((mint_amount - spend_amount) + redistribution) +# spender_new_decayed_balance = int(spender_new_base_balance - (spender_new_base_balance * (self.tax_level / 1000000))) +# +# o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) +# r = self.rpc.do(o) +# spender_actual_balance = c.parse_balance_of(r) +# logg.debug('rrr {} {}'.format(redistribution, spender_new_decayed_balance)) +# +# self.assertEqual(spender_actual_balance, spender_new_decayed_balance) +# if __name__ == '__main__': unittest.main() diff --git a/python/tests/test_redistribution_unit.py b/python/tests/test_redistribution_unit.py @@ -100,6 +100,9 @@ class TestRedistribution(TestDemurrageUnit): (tx_hash, o) = c.change_period(self.address, self.accounts[1]) self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) demurrage_amount = int((self.tax_level / 1000000) * mint_amount) @@ -126,6 +129,17 @@ class TestRedistribution(TestDemurrageUnit): r = self.rpc.do(o) supply = c.parse_total_supply(r) + + o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) + redistribution = self.rpc.do(o) + o = c.to_redistribution_supply(self.address, redistribution, sender_address=self.accounts[0]) + r = self.rpc.do(o) + supply = c.parse_to_redistribution_item(r) + o = c.demurrage_amount(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + demurrage = c.parse_demurrage_amount(r) + logg.debug('\ndemurrage {}\nsupply {}'.format(demurrage, supply)) + expected_balance = int(supply * (self.tax_level / 1000000)) expected_balance_tolerance = 1 diff --git a/python/tests/test_pure.py b/python/tests/test_remainder.py diff --git a/python/tests/test_single.py b/python/tests/test_single.py @@ -28,6 +28,7 @@ testdir = os.path.dirname(__file__) class TestRedistributionSingle(TestDemurrageSingle): + def test_single_even_if_multiple(self): mint_amount = 100000000 diff --git a/solidity/DemurrageTokenSingleCap.sol b/solidity/DemurrageTokenSingleCap.sol @@ -21,7 +21,9 @@ contract DemurrageTokenSingleCap { uint128 public demurrageAmount; // Cached demurrage period; the period for which demurrageAmount was calculated - uint128 public demurragePeriod; + //uint128 public demurragePeriod; + // Cached demurrage timestamp; the timestamp for which demurrageAmount was last calculated + uint256 public demurrageTimestamp; // Implements EIP172 address public owner; @@ -103,10 +105,11 @@ contract DemurrageTokenSingleCap { decimals = _decimals; // Demurrage setup - periodStart = block.timestamp; + demurrageTimestamp = block.timestamp; + periodStart = demurrageTimestamp; periodDuration = _periodMinutes * 60; demurrageAmount = uint128(ppmDivider * 1000000); // Represents 38 decimal places - demurragePeriod = 1; + //demurragePeriod = 1; taxLevel = _taxLevelMinute; // Represents 38 decimal places bytes32 initialRedistribution = toRedistribution(0, 1000000, 0, 1); redistributions.push(initialRedistribution); @@ -139,7 +142,8 @@ contract DemurrageTokenSingleCap { baseBalance = baseBalanceOf(_account); - periodCount = actualPeriod() - demurragePeriod; + //periodCount = actualPeriod() - demurragePeriod; + periodCount = getMinutesDelta(demurrageTimestamp); currentDemurragedAmount = uint128(decayBy(demurrageAmount, periodCount)); @@ -237,10 +241,12 @@ contract DemurrageTokenSingleCap { // Save the current total supply amount to the current redistribution period function saveRedistributionSupply() private returns (bool) { uint256 currentRedistribution; + uint256 grownSupply; + grownSupply = growBy(totalSupply, 1); currentRedistribution = uint256(redistributions[redistributions.length-1]); currentRedistribution &= (~maskRedistributionValue); - currentRedistribution |= (totalSupply << shiftRedistributionValue); + currentRedistribution |= (grownSupply << shiftRedistributionValue); redistributions[redistributions.length-1] = bytes32(currentRedistribution); return true; @@ -270,29 +276,36 @@ contract DemurrageTokenSingleCap { uint256 unit; redistributionSupply = toRedistributionSupply(_redistribution); - - unit = (redistributionSupply * taxLevel) / 1000000; + unit = redistributionSupply * (ppmDivider - (demurrageAmount / 1000000)); increaseBaseBalance(sinkAddress, unit / ppmDivider); return unit; } + // Calculate the time delta in whole minutes passed between given timestamp and current timestamp + function getMinutesDelta(uint256 _lastTimestamp) public view returns (uint256) { + return (block.timestamp - _lastTimestamp) / 60; + } + // Calculate and cache the demurrage value corresponding to the (period of the) time of the method call function applyDemurrage() public returns (bool) { uint128 epochPeriodCount; - uint128 periodCount; + uint256 periodCount; uint256 lastDemurrageAmount; uint256 newDemurrageAmount; - epochPeriodCount = actualPeriod(); - periodCount = epochPeriodCount - demurragePeriod; + //epochPeriodCount = actualPeriod(); + //periodCount = epochPeriodCount - demurragePeriod; + + periodCount = getMinutesDelta(demurrageTimestamp); if (periodCount == 0) { return false; } lastDemurrageAmount = demurrageAmount; demurrageAmount = uint128(decayBy(lastDemurrageAmount, periodCount)); - demurragePeriod = epochPeriodCount; - emit Decayed(epochPeriodCount, periodCount, lastDemurrageAmount, demurrageAmount); + //demurragePeriod = epochPeriodCount; + demurrageTimestamp = periodStart + (periodCount * 60); + emit Decayed(block.timestamp, periodCount, lastDemurrageAmount, demurrageAmount); return true; }