evm-tokenvote

Voting machine using ERC20 tokens as votes.
Log | Files | Refs | README

commit 7beca73b186995c6143036b9ccedf5d1ac5a1392
parent d316071755dfa8ef8b12176ffd1b19f30a7ba8a9
Author: lash <dev@holbrook.no>
Date:   Sun,  7 May 2023 10:06:16 +0100

Make supply protection during vote optional

Diffstat:
Mpython/evm_tokenvote/data/Voter.bin | 4++--
Mpython/evm_tokenvote/data/Voter.json | 2+-
Mpython/evm_tokenvote/data/Voter.metadata.json | 2+-
Mpython/evm_tokenvote/unittest/base.py | 4++--
Mpython/evm_tokenvote/voter.py | 7++++---
Mpython/tests/test_base.py | 3++-
Apython/tests/test_protect.py | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msolidity/Voter.sol | 46++++++++++++++++++++++++++++++++++------------
8 files changed, 116 insertions(+), 22 deletions(-)

diff --git a/python/evm_tokenvote/data/Voter.bin b/python/evm_tokenvote/data/Voter.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b50604051620038f5380380620038f583398181016040528101906200003791906200042e565b6200004162000264565b836000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600181908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000155602082015181600101908051906020019062000157929190620002e2565b5060408201518160020190805190602001906200017692919062000334565b50606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548162ffffff021916908362ffffff1602179055506101008201518160070160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160070160176101000a81548160ff021916908360ff1602179055506101408201518160070160186101000a81548160ff021916908360ff16021790555050506001600481905550505050506200048a565b60405180610160016040528060008019168152602001606081526020016060815260200160008152602001600081526020016000815260200160008152602001600062ffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b82805482825590600052602060002090810192821562000321579160200282015b828111156200032057825182559160200191906001019062000303565b5b50905062000330919062000386565b5090565b82805482825590600052602060002090810192821562000373579160200282015b828111156200037257825182559160200191906001019062000355565b5b509050620003829190620003a5565b5090565b5b80821115620003a157600081600090555060010162000387565b5090565b5b80821115620003c0576000816000905550600101620003a6565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620003f682620003c9565b9050919050565b6200040881620003e9565b81146200041457600080fd5b50565b6000815190506200042881620003fd565b92915050565b6000806000606084860312156200044a5762000449620003c4565b5b60006200045a8682870162000417565b93505060206200046d8682870162000417565b9250506040620004808682870162000417565b9150509250925092565b61345b806200049a6000396000f3fe608060405234801561001057600080fd5b506004361061011d576000357c010000000000000000000000000000000000000000000000000000000090048063826d9873116100b4578063ba32941411610083578063ba3294141461032c578063c7f758a81461035c578063e99a943e1461038c578063fc0c546a146103bc5761011d565b8063826d98731461026c578063843851911461029c5780638bb52213146102cc578063b05c65ba146102fc5761011d565b806341ec6870116100f057806341ec6870146101d05780634bb278f3146101ee578063509bd3371461020c57806370a082311461023c5761011d565b80630121b93f146101225780631ce30927146101525780632e1a7d4d146101825780633ccfd60b146101b2575b600080fd5b61013c6004803603810190610137919061225d565b6103da565b60405161014991906122a5565b60405180910390f35b61016c600480360381019061016791906122c0565b610456565b6040516101799190612319565b60405180910390f35b61019c6004803603810190610197919061225d565b6104b2565b6040516101a99190612343565b60405180910390f35b6101ba610544565b6040516101c79190612343565b60405180910390f35b6101d86108a1565b6040516101e5919061264b565b60405180910390f35b6101f6610ad3565b60405161020391906122a5565b60405180910390f35b610226600480360381019061022191906122c0565b610c78565b60405161023391906122a5565b60405180910390f35b61025660048036038101906102519190612699565b610d9c565b6040516102639190612343565b60405180910390f35b6102866004803603810190610281919061225d565b610db4565b60405161029391906122a5565b60405180910390f35b6102b660048036038101906102b1919061225d565b610ecb565b6040516102c39190612343565b60405180910390f35b6102e660048036038101906102e191906126f2565b610f0d565b6040516102f391906122a5565b60405180910390f35b610316600480360381019061031191906128e3565b6111e2565b6040516103239190612343565b60405180910390f35b610346600480360381019061034191906122c0565b611514565b6040516103539190612343565b60405180910390f35b6103766004803603810190610371919061225d565b6115d0565b604051610383919061264b565b60405180910390f35b6103a660048036038101906103a19190612966565b6117ad565b6040516103b39190612343565b60405180910390f35b6103c46117c7565b6040516103d191906129c8565b60405180910390f35b60008061040933600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166117eb565b60016004548154811061041f5761041e6129e3565b5b90600052602060002090600802019050600281600101805490501061044357600080fd5b61044e600084610c78565b915050919050565b600080600180856104679190612a41565b81548110610478576104776129e3565b5b9060005260206000209060080201905080600101838154811061049e5761049d6129e3565b5b906000526020600020015491505092915050565b6000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548214610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052c90612ad2565b60405180910390fd5b61053d610544565b9050919050565b600080600060606000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600454600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403610658576001600454815481106105ed576105ec6129e3565b5b90600052602060002090600802019350600060028560070160179054906101000a900460ff161660ff1611610657576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064e90612b3e565b60405180910390fd5b5b6000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16338260405160240161072c929190612b5e565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516107b69190612bf8565b6000604051808303816000865af19150503d80600081146107f3576040519150601f19603f3d011682016040523d82523d6000602084013e6107f8565b606091505b50809350819450505082610841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083890612c5b565b60405180910390fd5b818060200190518101906108559190612ca7565b925082610897576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088e90612d20565b60405180910390fd5b8094505050505090565b6108a96120c1565b60006001600454815481106108c1576108c06129e3565b5b90600052602060002090600802019050600060018260070160179054906101000a900460ff161660ff161161092b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092290612d8c565b60405180910390fd5b8060405180610160016040529081600082015481526020016001820180548060200260200160405190810160405280929190818152602001828054801561099157602002820191906000526020600020905b81548152602001906001019080831161097d575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156109e957602002820191906000526020600020905b8154815260200190600101908083116109d5575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016007820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016007820160179054906101000a900460ff1660ff1660ff1681526020016007820160189054906101000a900460ff1660ff1660ff168152505091505090565b6000806000600160045481548110610aee57610aed6129e3565b5b90600052602060002090600802019150600060028360070160179054906101000a900460ff161660ff1614610b58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4f90612df8565b60405180910390fd5b6000610b63836119c4565b03610b7357600092505050610c75565b60028260070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff160217905550610bac82611c2f565b610be95760088260070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060019050610bea565b5b801515600060808460070160179054906101000a900460ff161660ff161115156001600454610c199190612e18565b7f2d899e808be4b1d81a259d3f56d6d5c829a7cc913a35373a29f6363ebbb2c6c38560050154604051610c4c9190612343565b60405180910390a4600160046000828254610c679190612a41565b925050819055508015925050505b90565b600080610ca733600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166117eb565b600160045481548110610cbd57610cbc6129e3565b5b90600052602060002090600802019050610cd681611c7a565b610ce4576000915050610d96565b600081600101805490501115610d3e5780600101805490508410610d3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3490612e98565b60405180910390fd5b5b610d488184611e0a565b600081600101805490501115610d905782816002018581548110610d6f57610d6e6129e3565b5b906000526020600020016000828254610d889190612a41565b925050819055505b60019150505b92915050565b60056020528060005260406000206000915090505481565b6000806000610de533600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166117eb565b600160045481548110610dfb57610dfa6129e3565b5b90600052602060002090600802019150610e1482611c7a565b610e2357600092505050610ec6565b610e2d8285611e0a565b83826003016000828254610e419190612a41565b92505081905550620f42408260030154610e5b9190612eb8565b90508160070160009054906101000a900462ffffff1662ffffff16826004015482610e869190612f29565b10610ebf5760406080178260070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055505b6001925050505b919050565b60008060018084610edc9190612a41565b81548110610eed57610eec6129e3565b5b906000526020600020906008020190508060010180549050915050919050565b6000806000806000806000806001808b610f279190612a41565b81548110610f3857610f376129e3565b5b90600052602060002090600802019650600060408860070160179054906101000a900460ff161660ff1603610faf574387600601541115610fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa590612b3e565b60405180910390fd5b5b600060048860070160179054906101000a900460ff161660ff161115610fdf5760009750505050505050506111dc565b600087600101805490500361102e5760048760070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060019750505050505050506111dc565b8660070160189054906101000a900460ff169150866001018054905089836110569190612f5a565b60ff161115611075578187600101805490506110729190612f8f565b98505b81896110819190612f5a565b98508660070160179054906101000a900460ff1690508195505b8860ff168660ff16101561112a57866002018660ff16815481106110c2576110c16129e3565b5b906000526020600020015492506000831180156110de57508383145b156110ee57601081179050611108565b83831115611107578293508560ff169450601019811690505b5b6001826111159190612f5a565b9150858061112290612fc4565b96505061109b565b818760070160186101000a81548160ff021916908360ff160217905550808760070160176101000a81548160ff021916908360ff16021790555086600101805490508760070160189054906101000a900460ff1660ff16106111b75760048760070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055505b600060048860070160179054906101000a900460ff161660ff16119750505050505050505b92915050565b60006111ec6120c1565b60008061121b33600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166117eb565b610100875110611260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125790613039565b60405180910390fd5b3383610100019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505087836000018181525050868360200181905250865167ffffffffffffffff8111156112c7576112c6612774565b5b6040519080825280602002602001820160405280156112f55781602001602082028036833780820191505090505b508360400181905250848360e0019062ffffff16908162ffffff168152505085436113209190612a41565b9050808360c00181815250506001805490509150600183610120019060ff16908160ff1681525050600183908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000155602082015181600101908051906020019061139a92919061213f565b5060408201518160020190805190602001906113b792919061218c565b50606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548162ffffff021916908362ffffff1602179055506101008201518160070160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160070160176101000a81548160ff021916908360ff1602179055506101408201518160070160186101000a81548160ff021916908360ff16021790555050506114bd600183815481106114aa576114a96129e3565b5b90600052602060002090600802016119c4565b8360800181815250506001826114d39190612e18565b8562ffffff16827f5a41400aa51d78e9e5ca645b0d045817eaa7d90e4344d773fdbe24ffb183d3ce60405160405180910390a4819350505050949350505050565b600080600180856115259190612a41565b81548110611536576115356129e3565b5b9060005260206000209060080201905060008160010180549050036115a55760008314611598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158f906130a5565b60405180910390fd5b80600501549150506115ca565b8060020183815481106115bb576115ba6129e3565b5b90600052602060002001549150505b92915050565b6115d86120c1565b600180836115e69190612a41565b815481106115f7576115f66129e3565b5b906000526020600020906008020160405180610160016040529081600082015481526020016001820180548060200260200160405190810160405280929190818152602001828054801561166a57602002820191906000526020600020905b815481526020019060010190808311611656575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156116c257602002820191906000526020600020905b8154815260200190600101908083116116ae575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016007820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016007820160179054906101000a900460ff1660ff1660ff1681526020016007820160189054906101000a900460ff1660ff1660ff16815250509050919050565b600060606117bd858286866111e2565b9150509392505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006060600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361182a5750506119c0565b8273ffffffffffffffffffffffffffffffffffffffff168460405160240161185291906129c8565b6040516020818303038152906040527f3ef25013000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516118dc9190612bf8565b6000604051808303816000865af19150503d8060008114611919576040519150601f19603f3d011682016040523d82523d6000602084013e61191e565b606091505b50809250819350505081611967576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195e90613111565b60405180910390fd5b8080602001905181019061197b9190612ca7565b9150816119bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b49061317d565b60405180910390fd5b50505b5050565b600080606060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f18160ddd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611a939190612bf8565b6000604051808303816000865af19150503d8060008114611ad0576040519150601f19603f3d011682016040523d82523d6000602084013e611ad5565b606091505b50809350819450505082611b1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1590612c5b565b60405180910390fd5b81806020019051810190611b3291906131b2565b905060008111611b77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6e9061322b565b60405180910390fd5b6000856004015403611b9157808560040181905550611c23565b84600401548114611c225760208560070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060028560070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff160217905550600160046000828254611c0f9190612a41565b9250508190555060009350505050611c2a565b5b8093505050505b919050565b600080620f42408360050154611c459190612eb8565b90508260070160009054906101000a900462ffffff1662ffffff16836004015482611c709190612f29565b1015915050919050565b60008060018360070160179054906101000a900460ff161660ff1611611cd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ccc90613297565b60405180910390fd5b6000611ce0836119c4565b03611cee5760009050611e05565b43826006015411611d34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2b90613303565b60405180910390fd5b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611e0057600454600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611dff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df69061336f565b60405180910390fd5b5b600190505b919050565b6000606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16333085604051602401611e5a939291906133ee565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611ee49190612bf8565b6000604051808303816000865af19150503d8060008114611f21576040519150601f19603f3d011682016040523d82523d6000602084013e611f26565b606091505b50809250819350505081611f6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6690612c5b565b60405180910390fd5b80806020019051810190611f839190612ca7565b915081611fc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fbc90612d20565b60405180910390fd5b600454600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555082600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461205a9190612a41565b92505081905550828460050160008282546120759190612a41565b9250508190555061208584611c2f565b156120bb5760408460070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055505b50505050565b60405180610160016040528060008019168152602001606081526020016060815260200160008152602001600081526020016000815260200160008152602001600062ffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b82805482825590600052602060002090810192821561217b579160200282015b8281111561217a57825182559160200191906001019061215f565b5b50905061218891906121d9565b5090565b8280548282559060005260206000209081019282156121c8579160200282015b828111156121c75782518255916020019190600101906121ac565b5b5090506121d591906121f6565b5090565b5b808211156121f25760008160009055506001016121da565b5090565b5b8082111561220f5760008160009055506001016121f7565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61223a81612227565b811461224557600080fd5b50565b60008135905061225781612231565b92915050565b6000602082840312156122735761227261221d565b5b600061228184828501612248565b91505092915050565b60008115159050919050565b61229f8161228a565b82525050565b60006020820190506122ba6000830184612296565b92915050565b600080604083850312156122d7576122d661221d565b5b60006122e585828601612248565b92505060206122f685828601612248565b9150509250929050565b6000819050919050565b61231381612300565b82525050565b600060208201905061232e600083018461230a565b92915050565b61233d81612227565b82525050565b60006020820190506123586000830184612334565b92915050565b61236781612300565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006123a5838361235e565b60208301905092915050565b6000602082019050919050565b60006123c98261236d565b6123d38185612378565b93506123de83612389565b8060005b8381101561240f5781516123f68882612399565b9750612401836123b1565b9250506001810190506123e2565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61245181612227565b82525050565b60006124638383612448565b60208301905092915050565b6000602082019050919050565b60006124878261241c565b6124918185612427565b935061249c83612438565b8060005b838110156124cd5781516124b48882612457565b97506124bf8361246f565b9250506001810190506124a0565b5085935050505092915050565b600062ffffff82169050919050565b6124f2816124da565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612523826124f8565b9050919050565b61253381612518565b82525050565b600060ff82169050919050565b61254f81612539565b82525050565b60006101608301600083015161256e600086018261235e565b506020830151848203602086015261258682826123be565b915050604083015184820360408601526125a0828261247c565b91505060608301516125b56060860182612448565b5060808301516125c86080860182612448565b5060a08301516125db60a0860182612448565b5060c08301516125ee60c0860182612448565b5060e083015161260160e08601826124e9565b5061010083015161261661010086018261252a565b5061012083015161262b610120860182612546565b50610140830151612640610140860182612546565b508091505092915050565b600060208201905081810360008301526126658184612555565b905092915050565b61267681612518565b811461268157600080fd5b50565b6000813590506126938161266d565b92915050565b6000602082840312156126af576126ae61221d565b5b60006126bd84828501612684565b91505092915050565b6126cf81612539565b81146126da57600080fd5b50565b6000813590506126ec816126c6565b92915050565b600080604083850312156127095761270861221d565b5b600061271785828601612248565b9250506020612728858286016126dd565b9150509250929050565b61273b81612300565b811461274657600080fd5b50565b60008135905061275881612732565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6127ac82612763565b810181811067ffffffffffffffff821117156127cb576127ca612774565b5b80604052505050565b60006127de612213565b90506127ea82826127a3565b919050565b600067ffffffffffffffff82111561280a57612809612774565b5b602082029050602081019050919050565b600080fd5b600061283361282e846127ef565b6127d4565b905080838252602082019050602084028301858111156128565761285561281b565b5b835b8181101561287f578061286b8882612749565b845260208401935050602081019050612858565b5050509392505050565b600082601f83011261289e5761289d61275e565b5b81356128ae848260208601612820565b91505092915050565b6128c0816124da565b81146128cb57600080fd5b50565b6000813590506128dd816128b7565b92915050565b600080600080608085870312156128fd576128fc61221d565b5b600061290b87828801612749565b945050602085013567ffffffffffffffff81111561292c5761292b612222565b5b61293887828801612889565b935050604061294987828801612248565b925050606061295a878288016128ce565b91505092959194509250565b60008060006060848603121561297f5761297e61221d565b5b600061298d86828701612749565b935050602061299e86828701612248565b92505060406129af868287016128ce565b9150509250925092565b6129c281612518565b82525050565b60006020820190506129dd60008301846129b9565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612a4c82612227565b9150612a5783612227565b9250828201905080821115612a6f57612a6e612a12565b5b92915050565b600082825260208201905092915050565b7f4552525f4d5553545f57495448445241575f414c4c0000000000000000000000600082015250565b6000612abc601583612a75565b9150612ac782612a86565b602082019050919050565b60006020820190508181036000830152612aeb81612aaf565b9050919050565b7f4552525f5052454d415455524500000000000000000000000000000000000000600082015250565b6000612b28600d83612a75565b9150612b3382612af2565b602082019050919050565b60006020820190508181036000830152612b5781612b1b565b9050919050565b6000604082019050612b7360008301856129b9565b612b806020830184612334565b9392505050565b600081519050919050565b600081905092915050565b60005b83811015612bbb578082015181840152602081019050612ba0565b60008484015250505050565b6000612bd282612b87565b612bdc8185612b92565b9350612bec818560208601612b9d565b80840191505092915050565b6000612c048284612bc7565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b6000612c45600983612a75565b9150612c5082612c0f565b602082019050919050565b60006020820190508181036000830152612c7481612c38565b9050919050565b612c848161228a565b8114612c8f57600080fd5b50565b600081519050612ca181612c7b565b92915050565b600060208284031215612cbd57612cbc61221d565b5b6000612ccb84828501612c92565b91505092915050565b7f4552525f5452414e534645520000000000000000000000000000000000000000600082015250565b6000612d0a600c83612a75565b9150612d1582612cd4565b602082019050919050565b60006020820190508181036000830152612d3981612cfd565b9050919050565b7f4552525f4e4f5f43555252454e545f50524f504f53414c000000000000000000600082015250565b6000612d76601783612a75565b9150612d8182612d40565b602082019050919050565b60006020820190508181036000830152612da581612d69565b9050919050565b7f4552525f414c52454144595f53544154455f46494e414c000000000000000000600082015250565b6000612de2601783612a75565b9150612ded82612dac565b602082019050919050565b60006020820190508181036000830152612e1181612dd5565b9050919050565b6000612e2382612227565b9150612e2e83612227565b9250828203905081811115612e4657612e45612a12565b5b92915050565b7f4552525f4f5054494f4e5f494e56414c49440000000000000000000000000000600082015250565b6000612e82601283612a75565b9150612e8d82612e4c565b602082019050919050565b60006020820190508181036000830152612eb181612e75565b9050919050565b6000612ec382612227565b9150612ece83612227565b9250828202612edc81612227565b91508282048414831517612ef357612ef2612a12565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612f3482612227565b9150612f3f83612227565b925082612f4f57612f4e612efa565b5b828204905092915050565b6000612f6582612539565b9150612f7083612539565b9250828201905060ff811115612f8957612f88612a12565b5b92915050565b6000612f9a82612539565b9150612fa583612539565b9250828203905060ff811115612fbe57612fbd612a12565b5b92915050565b6000612fcf82612539565b915060ff8203612fe257612fe1612a12565b5b600182019050919050565b7f4552525f544f4f5f4d414e595f4f5054494f4e53000000000000000000000000600082015250565b6000613023601483612a75565b915061302e82612fed565b602082019050919050565b6000602082019050818103600083015261305281613016565b9050919050565b7f4552525f4e4f5f4f5054494f4e53000000000000000000000000000000000000600082015250565b600061308f600e83612a75565b915061309a82613059565b602082019050919050565b600060208201905081810360008301526130be81613082565b9050919050565b7f4552525f52454749535452590000000000000000000000000000000000000000600082015250565b60006130fb600c83612a75565b9150613106826130c5565b602082019050919050565b6000602082019050818103600083015261312a816130ee565b9050919050565b7f4552525f554e415554485f4143434f554e540000000000000000000000000000600082015250565b6000613167601283612a75565b915061317282613131565b602082019050919050565b600060208201905081810360008301526131968161315a565b9050919050565b6000815190506131ac81612231565b92915050565b6000602082840312156131c8576131c761221d565b5b60006131d68482850161319d565b91505092915050565b7f4552525f5a45524f5f535550504c590000000000000000000000000000000000600082015250565b6000613215600f83612a75565b9150613220826131df565b602082019050919050565b6000602082019050818103600083015261324481613208565b9050919050565b7f4552525f50524f504f53414c5f494e4143544956450000000000000000000000600082015250565b6000613281601583612a75565b915061328c8261324b565b602082019050919050565b600060208201905081810360008301526132b081613274565b9050919050565b7f4552525f444541444c494e450000000000000000000000000000000000000000600082015250565b60006132ed600c83612a75565b91506132f8826132b7565b602082019050919050565b6000602082019050818103600083015261331c816132e0565b9050919050565b7f4552525f57495448445241575f46495253540000000000000000000000000000600082015250565b6000613359601283612a75565b915061336482613323565b602082019050919050565b600060208201905081810360008301526133888161334c565b9050919050565b6000819050919050565b60006133b46133af6133aa846124f8565b61338f565b6124f8565b9050919050565b60006133c682613399565b9050919050565b60006133d8826133bb565b9050919050565b6133e8816133cd565b82525050565b600060608201905061340360008301866129b9565b61341060208301856133df565b61341d6040830184612334565b94935050505056fea2646970667358221220404b6dba1e7886412f41bdc047a6bf6c4754d19eb0b17541fb904266d1eff25264736f6c63430008130033 -\ No newline at end of file +60806040523480156200001157600080fd5b50604051620039a9380380620039a9833981810160405281019062000037919062000486565b620000416200027f565b846000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600181908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000155602082015181600101908051906020019062000157929190620002fd565b506040820151816002019080519060200190620001769291906200034f565b50606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548162ffffff021916908362ffffff1602179055506101008201518160070160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160070160176101000a81548160ff021916908360ff1602179055506101408201518160070160186101000a81548160ff021916908360ff1602179055505050600160048190555083600560006101000a81548160ff0219169083151502179055505050505050620004f8565b60405180610160016040528060008019168152602001606081526020016060815260200160008152602001600081526020016000815260200160008152602001600062ffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b8280548282559060005260206000209081019282156200033c579160200282015b828111156200033b5782518255916020019190600101906200031e565b5b5090506200034b9190620003a1565b5090565b8280548282559060005260206000209081019282156200038e579160200282015b828111156200038d57825182559160200191906001019062000370565b5b5090506200039d9190620003c0565b5090565b5b80821115620003bc576000816000905550600101620003a2565b5090565b5b80821115620003db576000816000905550600101620003c1565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200041182620003e4565b9050919050565b620004238162000404565b81146200042f57600080fd5b50565b600081519050620004438162000418565b92915050565b60008115159050919050565b620004608162000449565b81146200046c57600080fd5b50565b600081519050620004808162000455565b92915050565b60008060008060808587031215620004a357620004a2620003df565b5b6000620004b38782880162000432565b9450506020620004c6878288016200046f565b9350506040620004d98782880162000432565b9250506060620004ec8782880162000432565b91505092959194509250565b6134a180620005086000396000f3fe608060405234801561001057600080fd5b506004361061011d576000357c010000000000000000000000000000000000000000000000000000000090048063826d9873116100b4578063ba32941411610083578063ba3294141461032c578063c7f758a81461035c578063e99a943e1461038c578063fc0c546a146103bc5761011d565b8063826d98731461026c578063843851911461029c5780638bb52213146102cc578063b05c65ba146102fc5761011d565b806341ec6870116100f057806341ec6870146101d05780634bb278f3146101ee578063509bd3371461020c57806370a082311461023c5761011d565b80630121b93f146101225780631ce30927146101525780632e1a7d4d146101825780633ccfd60b146101b2575b600080fd5b61013c600480360381019061013791906122a3565b6103da565b60405161014991906122eb565b60405180910390f35b61016c60048036038101906101679190612306565b610456565b604051610179919061235f565b60405180910390f35b61019c600480360381019061019791906122a3565b6104b2565b6040516101a99190612389565b60405180910390f35b6101ba610544565b6040516101c79190612389565b60405180910390f35b6101d86108a1565b6040516101e59190612691565b60405180910390f35b6101f6610ad3565b60405161020391906122eb565b60405180910390f35b61022660048036038101906102219190612306565b610c78565b60405161023391906122eb565b60405180910390f35b610256600480360381019061025191906126df565b610d9c565b6040516102639190612389565b60405180910390f35b610286600480360381019061028191906122a3565b610db4565b60405161029391906122eb565b60405180910390f35b6102b660048036038101906102b191906122a3565b610ecb565b6040516102c39190612389565b60405180910390f35b6102e660048036038101906102e19190612738565b610f0d565b6040516102f391906122eb565b60405180910390f35b61031660048036038101906103119190612929565b6111e2565b6040516103239190612389565b60405180910390f35b61034660048036038101906103419190612306565b611514565b6040516103539190612389565b60405180910390f35b610376600480360381019061037191906122a3565b6115d0565b6040516103839190612691565b60405180910390f35b6103a660048036038101906103a191906129ac565b6117ad565b6040516103b39190612389565b60405180910390f35b6103c46117c7565b6040516103d19190612a0e565b60405180910390f35b60008061040933600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166117eb565b60016004548154811061041f5761041e612a29565b5b90600052602060002090600802019050600281600101805490501061044357600080fd5b61044e600084610c78565b915050919050565b600080600180856104679190612a87565b8154811061047857610477612a29565b5b9060005260206000209060080201905080600101838154811061049e5761049d612a29565b5b906000526020600020015491505092915050565b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548214610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052c90612b18565b60405180910390fd5b61053d610544565b9050919050565b600080600060606000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600454600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403610658576001600454815481106105ed576105ec612a29565b5b90600052602060002090600802019350600060028560070160179054906101000a900460ff161660ff1611610657576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064e90612b84565b60405180910390fd5b5b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16338260405160240161072c929190612ba4565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516107b69190612c3e565b6000604051808303816000865af19150503d80600081146107f3576040519150601f19603f3d011682016040523d82523d6000602084013e6107f8565b606091505b50809350819450505082610841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083890612ca1565b60405180910390fd5b818060200190518101906108559190612ced565b925082610897576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088e90612d66565b60405180910390fd5b8094505050505090565b6108a9612107565b60006001600454815481106108c1576108c0612a29565b5b90600052602060002090600802019050600060018260070160179054906101000a900460ff161660ff161161092b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092290612dd2565b60405180910390fd5b8060405180610160016040529081600082015481526020016001820180548060200260200160405190810160405280929190818152602001828054801561099157602002820191906000526020600020905b81548152602001906001019080831161097d575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156109e957602002820191906000526020600020905b8154815260200190600101908083116109d5575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016007820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016007820160179054906101000a900460ff1660ff1660ff1681526020016007820160189054906101000a900460ff1660ff1660ff168152505091505090565b6000806000600160045481548110610aee57610aed612a29565b5b90600052602060002090600802019150600060028360070160179054906101000a900460ff161660ff1614610b58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4f90612e3e565b60405180910390fd5b6000610b63836119c4565b03610b7357600092505050610c75565b60028260070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff160217905550610bac82611c75565b610be95760088260070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060019050610bea565b5b801515600060808460070160179054906101000a900460ff161660ff161115156001600454610c199190612e5e565b7f2d899e808be4b1d81a259d3f56d6d5c829a7cc913a35373a29f6363ebbb2c6c38560050154604051610c4c9190612389565b60405180910390a4600160046000828254610c679190612a87565b925050819055508015925050505b90565b600080610ca733600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166117eb565b600160045481548110610cbd57610cbc612a29565b5b90600052602060002090600802019050610cd681611cc0565b610ce4576000915050610d96565b600081600101805490501115610d3e5780600101805490508410610d3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3490612ede565b60405180910390fd5b5b610d488184611e50565b600081600101805490501115610d905782816002018581548110610d6f57610d6e612a29565b5b906000526020600020016000828254610d889190612a87565b925050819055505b60019150505b92915050565b60066020528060005260406000206000915090505481565b6000806000610de533600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166117eb565b600160045481548110610dfb57610dfa612a29565b5b90600052602060002090600802019150610e1482611cc0565b610e2357600092505050610ec6565b610e2d8285611e50565b83826003016000828254610e419190612a87565b92505081905550620f42408260030154610e5b9190612efe565b90508160070160009054906101000a900462ffffff1662ffffff16826004015482610e869190612f6f565b10610ebf5760406080178260070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055505b6001925050505b919050565b60008060018084610edc9190612a87565b81548110610eed57610eec612a29565b5b906000526020600020906008020190508060010180549050915050919050565b6000806000806000806000806001808b610f279190612a87565b81548110610f3857610f37612a29565b5b90600052602060002090600802019650600060408860070160179054906101000a900460ff161660ff1603610faf574387600601541115610fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa590612b84565b60405180910390fd5b5b600060048860070160179054906101000a900460ff161660ff161115610fdf5760009750505050505050506111dc565b600087600101805490500361102e5760048760070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060019750505050505050506111dc565b8660070160189054906101000a900460ff169150866001018054905089836110569190612fa0565b60ff161115611075578187600101805490506110729190612fd5565b98505b81896110819190612fa0565b98508660070160179054906101000a900460ff1690508195505b8860ff168660ff16101561112a57866002018660ff16815481106110c2576110c1612a29565b5b906000526020600020015492506000831180156110de57508383145b156110ee57601081179050611108565b83831115611107578293508560ff169450601019811690505b5b6001826111159190612fa0565b915085806111229061300a565b96505061109b565b818760070160186101000a81548160ff021916908360ff160217905550808760070160176101000a81548160ff021916908360ff16021790555086600101805490508760070160189054906101000a900460ff1660ff16106111b75760048760070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055505b600060048860070160179054906101000a900460ff161660ff16119750505050505050505b92915050565b60006111ec612107565b60008061121b33600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166117eb565b610100875110611260576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112579061307f565b60405180910390fd5b3383610100019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505087836000018181525050868360200181905250865167ffffffffffffffff8111156112c7576112c66127ba565b5b6040519080825280602002602001820160405280156112f55781602001602082028036833780820191505090505b508360400181905250848360e0019062ffffff16908162ffffff168152505085436113209190612a87565b9050808360c00181815250506001805490509150600183610120019060ff16908160ff1681525050600183908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000155602082015181600101908051906020019061139a929190612185565b5060408201518160020190805190602001906113b79291906121d2565b50606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548162ffffff021916908362ffffff1602179055506101008201518160070160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160070160176101000a81548160ff021916908360ff1602179055506101408201518160070160186101000a81548160ff021916908360ff16021790555050506114bd600183815481106114aa576114a9612a29565b5b90600052602060002090600802016119c4565b8360800181815250506001826114d39190612e5e565b8562ffffff16827f5a41400aa51d78e9e5ca645b0d045817eaa7d90e4344d773fdbe24ffb183d3ce60405160405180910390a4819350505050949350505050565b600080600180856115259190612a87565b8154811061153657611535612a29565b5b9060005260206000209060080201905060008160010180549050036115a55760008314611598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158f906130eb565b60405180910390fd5b80600501549150506115ca565b8060020183815481106115bb576115ba612a29565b5b90600052602060002001549150505b92915050565b6115d8612107565b600180836115e69190612a87565b815481106115f7576115f6612a29565b5b906000526020600020906008020160405180610160016040529081600082015481526020016001820180548060200260200160405190810160405280929190818152602001828054801561166a57602002820191906000526020600020905b815481526020019060010190808311611656575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156116c257602002820191906000526020600020905b8154815260200190600101908083116116ae575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016007820160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016007820160179054906101000a900460ff1660ff1660ff1681526020016007820160189054906101000a900460ff1660ff1660ff16815250509050919050565b600060606117bd858286866111e2565b9150509392505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006060600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361182a5750506119c0565b8273ffffffffffffffffffffffffffffffffffffffff16846040516024016118529190612a0e565b6040516020818303038152906040527f3ef25013000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516118dc9190612c3e565b6000604051808303816000865af19150503d8060008114611919576040519150601f19603f3d011682016040523d82523d6000602084013e61191e565b606091505b50809250819350505081611967576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195e90613157565b60405180910390fd5b8080602001905181019061197b9190612ced565b9150816119bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b4906131c3565b60405180910390fd5b50505b5050565b600080606060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f18160ddd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611a939190612c3e565b6000604051808303816000865af19150503d8060008114611ad0576040519150601f19603f3d011682016040523d82523d6000602084013e611ad5565b606091505b50809350819450505082611b1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1590612ca1565b60405180910390fd5b81806020019051810190611b3291906131f8565b905060008111611b77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6e90613271565b60405180910390fd5b6000856004015403611b9157808560040181905550611c69565b84600401548114611c685760208560070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060028560070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff160217905550600560009054906101000a900460ff1615611c6757600160046000828254611c249190612a87565b9250508190555060808560070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060009350505050611c70565b5b5b8093505050505b919050565b600080620f42408360050154611c8b9190612efe565b90508260070160009054906101000a900462ffffff1662ffffff16836004015482611cb69190612f6f565b1015915050919050565b60008060018360070160179054906101000a900460ff161660ff1611611d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d12906132dd565b60405180910390fd5b6000611d26836119c4565b03611d345760009050611e4b565b43826006015411611d7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7190613349565b60405180910390fd5b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611e4657600454600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3c906133b5565b60405180910390fd5b5b600190505b919050565b6000606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16333085604051602401611ea093929190613434565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611f2a9190612c3e565b6000604051808303816000865af19150503d8060008114611f67576040519150601f19603f3d011682016040523d82523d6000602084013e611f6c565b606091505b50809250819350505081611fb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fac90612ca1565b60405180910390fd5b80806020019051810190611fc99190612ced565b91508161200b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200290612d66565b60405180910390fd5b600454600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555082600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120a09190612a87565b92505081905550828460050160008282546120bb9190612a87565b925050819055506120cb84611c75565b156121015760408460070160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055505b50505050565b60405180610160016040528060008019168152602001606081526020016060815260200160008152602001600081526020016000815260200160008152602001600062ffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b8280548282559060005260206000209081019282156121c1579160200282015b828111156121c05782518255916020019190600101906121a5565b5b5090506121ce919061221f565b5090565b82805482825590600052602060002090810192821561220e579160200282015b8281111561220d5782518255916020019190600101906121f2565b5b50905061221b919061223c565b5090565b5b80821115612238576000816000905550600101612220565b5090565b5b8082111561225557600081600090555060010161223d565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6122808161226d565b811461228b57600080fd5b50565b60008135905061229d81612277565b92915050565b6000602082840312156122b9576122b8612263565b5b60006122c78482850161228e565b91505092915050565b60008115159050919050565b6122e5816122d0565b82525050565b600060208201905061230060008301846122dc565b92915050565b6000806040838503121561231d5761231c612263565b5b600061232b8582860161228e565b925050602061233c8582860161228e565b9150509250929050565b6000819050919050565b61235981612346565b82525050565b60006020820190506123746000830184612350565b92915050565b6123838161226d565b82525050565b600060208201905061239e600083018461237a565b92915050565b6123ad81612346565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006123eb83836123a4565b60208301905092915050565b6000602082019050919050565b600061240f826123b3565b61241981856123be565b9350612424836123cf565b8060005b8381101561245557815161243c88826123df565b9750612447836123f7565b925050600181019050612428565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6124978161226d565b82525050565b60006124a9838361248e565b60208301905092915050565b6000602082019050919050565b60006124cd82612462565b6124d7818561246d565b93506124e28361247e565b8060005b838110156125135781516124fa888261249d565b9750612505836124b5565b9250506001810190506124e6565b5085935050505092915050565b600062ffffff82169050919050565b61253881612520565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006125698261253e565b9050919050565b6125798161255e565b82525050565b600060ff82169050919050565b6125958161257f565b82525050565b6000610160830160008301516125b460008601826123a4565b50602083015184820360208601526125cc8282612404565b915050604083015184820360408601526125e682826124c2565b91505060608301516125fb606086018261248e565b50608083015161260e608086018261248e565b5060a083015161262160a086018261248e565b5060c083015161263460c086018261248e565b5060e083015161264760e086018261252f565b5061010083015161265c610100860182612570565b5061012083015161267161012086018261258c565b5061014083015161268661014086018261258c565b508091505092915050565b600060208201905081810360008301526126ab818461259b565b905092915050565b6126bc8161255e565b81146126c757600080fd5b50565b6000813590506126d9816126b3565b92915050565b6000602082840312156126f5576126f4612263565b5b6000612703848285016126ca565b91505092915050565b6127158161257f565b811461272057600080fd5b50565b6000813590506127328161270c565b92915050565b6000806040838503121561274f5761274e612263565b5b600061275d8582860161228e565b925050602061276e85828601612723565b9150509250929050565b61278181612346565b811461278c57600080fd5b50565b60008135905061279e81612778565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6127f2826127a9565b810181811067ffffffffffffffff82111715612811576128106127ba565b5b80604052505050565b6000612824612259565b905061283082826127e9565b919050565b600067ffffffffffffffff8211156128505761284f6127ba565b5b602082029050602081019050919050565b600080fd5b600061287961287484612835565b61281a565b9050808382526020820190506020840283018581111561289c5761289b612861565b5b835b818110156128c557806128b1888261278f565b84526020840193505060208101905061289e565b5050509392505050565b600082601f8301126128e4576128e36127a4565b5b81356128f4848260208601612866565b91505092915050565b61290681612520565b811461291157600080fd5b50565b600081359050612923816128fd565b92915050565b6000806000806080858703121561294357612942612263565b5b60006129518782880161278f565b945050602085013567ffffffffffffffff81111561297257612971612268565b5b61297e878288016128cf565b935050604061298f8782880161228e565b92505060606129a087828801612914565b91505092959194509250565b6000806000606084860312156129c5576129c4612263565b5b60006129d38682870161278f565b93505060206129e48682870161228e565b92505060406129f586828701612914565b9150509250925092565b612a088161255e565b82525050565b6000602082019050612a2360008301846129ff565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612a928261226d565b9150612a9d8361226d565b9250828201905080821115612ab557612ab4612a58565b5b92915050565b600082825260208201905092915050565b7f4552525f4d5553545f57495448445241575f414c4c0000000000000000000000600082015250565b6000612b02601583612abb565b9150612b0d82612acc565b602082019050919050565b60006020820190508181036000830152612b3181612af5565b9050919050565b7f4552525f5052454d415455524500000000000000000000000000000000000000600082015250565b6000612b6e600d83612abb565b9150612b7982612b38565b602082019050919050565b60006020820190508181036000830152612b9d81612b61565b9050919050565b6000604082019050612bb960008301856129ff565b612bc6602083018461237a565b9392505050565b600081519050919050565b600081905092915050565b60005b83811015612c01578082015181840152602081019050612be6565b60008484015250505050565b6000612c1882612bcd565b612c228185612bd8565b9350612c32818560208601612be3565b80840191505092915050565b6000612c4a8284612c0d565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b6000612c8b600983612abb565b9150612c9682612c55565b602082019050919050565b60006020820190508181036000830152612cba81612c7e565b9050919050565b612cca816122d0565b8114612cd557600080fd5b50565b600081519050612ce781612cc1565b92915050565b600060208284031215612d0357612d02612263565b5b6000612d1184828501612cd8565b91505092915050565b7f4552525f5452414e534645520000000000000000000000000000000000000000600082015250565b6000612d50600c83612abb565b9150612d5b82612d1a565b602082019050919050565b60006020820190508181036000830152612d7f81612d43565b9050919050565b7f4552525f4e4f5f43555252454e545f50524f504f53414c000000000000000000600082015250565b6000612dbc601783612abb565b9150612dc782612d86565b602082019050919050565b60006020820190508181036000830152612deb81612daf565b9050919050565b7f4552525f414c52454144595f53544154455f46494e414c000000000000000000600082015250565b6000612e28601783612abb565b9150612e3382612df2565b602082019050919050565b60006020820190508181036000830152612e5781612e1b565b9050919050565b6000612e698261226d565b9150612e748361226d565b9250828203905081811115612e8c57612e8b612a58565b5b92915050565b7f4552525f4f5054494f4e5f494e56414c49440000000000000000000000000000600082015250565b6000612ec8601283612abb565b9150612ed382612e92565b602082019050919050565b60006020820190508181036000830152612ef781612ebb565b9050919050565b6000612f098261226d565b9150612f148361226d565b9250828202612f228161226d565b91508282048414831517612f3957612f38612a58565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612f7a8261226d565b9150612f858361226d565b925082612f9557612f94612f40565b5b828204905092915050565b6000612fab8261257f565b9150612fb68361257f565b9250828201905060ff811115612fcf57612fce612a58565b5b92915050565b6000612fe08261257f565b9150612feb8361257f565b9250828203905060ff81111561300457613003612a58565b5b92915050565b60006130158261257f565b915060ff820361302857613027612a58565b5b600182019050919050565b7f4552525f544f4f5f4d414e595f4f5054494f4e53000000000000000000000000600082015250565b6000613069601483612abb565b915061307482613033565b602082019050919050565b600060208201905081810360008301526130988161305c565b9050919050565b7f4552525f4e4f5f4f5054494f4e53000000000000000000000000000000000000600082015250565b60006130d5600e83612abb565b91506130e08261309f565b602082019050919050565b60006020820190508181036000830152613104816130c8565b9050919050565b7f4552525f52454749535452590000000000000000000000000000000000000000600082015250565b6000613141600c83612abb565b915061314c8261310b565b602082019050919050565b6000602082019050818103600083015261317081613134565b9050919050565b7f4552525f554e415554485f4143434f554e540000000000000000000000000000600082015250565b60006131ad601283612abb565b91506131b882613177565b602082019050919050565b600060208201905081810360008301526131dc816131a0565b9050919050565b6000815190506131f281612277565b92915050565b60006020828403121561320e5761320d612263565b5b600061321c848285016131e3565b91505092915050565b7f4552525f5a45524f5f535550504c590000000000000000000000000000000000600082015250565b600061325b600f83612abb565b915061326682613225565b602082019050919050565b6000602082019050818103600083015261328a8161324e565b9050919050565b7f4552525f50524f504f53414c5f494e4143544956450000000000000000000000600082015250565b60006132c7601583612abb565b91506132d282613291565b602082019050919050565b600060208201905081810360008301526132f6816132ba565b9050919050565b7f4552525f444541444c494e450000000000000000000000000000000000000000600082015250565b6000613333600c83612abb565b915061333e826132fd565b602082019050919050565b6000602082019050818103600083015261336281613326565b9050919050565b7f4552525f57495448445241575f46495253540000000000000000000000000000600082015250565b600061339f601283612abb565b91506133aa82613369565b602082019050919050565b600060208201905081810360008301526133ce81613392565b9050919050565b6000819050919050565b60006133fa6133f56133f08461253e565b6133d5565b61253e565b9050919050565b600061340c826133df565b9050919050565b600061341e82613401565b9050919050565b61342e81613413565b82525050565b600060608201905061344960008301866129ff565b6134566020830185613425565b613463604083018461237a565b94935050505056fea264697066735822122015ee45df49404113dd7998dcae6c2dc12a9920c9012d24eb5d467c6b0f08fef964736f6c63430008130033 +\ No newline at end of file diff --git a/python/evm_tokenvote/data/Voter.json b/python/evm_tokenvote/data/Voter.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_voterRegistry","type":"address"},{"internalType":"address","name":"_proposerRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_blockDeadline","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"voteTargetPpm","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"indexed":true,"internalType":"bool","name":"_cancelled","type":"bool"},{"indexed":true,"internalType":"bool","name":"_insufficient","type":"bool"},{"indexed":false,"internalType":"uint256","name":"_totalVote","type":"uint256"}],"name":"ProposalCompleted","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentProposal","outputs":[{"components":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"internalType":"bytes32[]","name":"options","type":"bytes32[]"},{"internalType":"uint256[]","name":"optionVotes","type":"uint256[]"},{"internalType":"uint256","name":"cancelVotes","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"blockDeadline","type":"uint256"},{"internalType":"uint24","name":"targetVotePpm","type":"uint24"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint8","name":"scanCursor","type":"uint8"}],"internalType":"struct ERC20Vote.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"internalType":"uint256","name":"_optionIdx","type":"uint256"}],"name":"getOption","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"getProposal","outputs":[{"components":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"internalType":"bytes32[]","name":"options","type":"bytes32[]"},{"internalType":"uint256[]","name":"optionVotes","type":"uint256[]"},{"internalType":"uint256","name":"cancelVotes","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"blockDeadline","type":"uint256"},{"internalType":"uint24","name":"targetVotePpm","type":"uint24"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint8","name":"scanCursor","type":"uint8"}],"internalType":"struct ERC20Vote.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"optionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_description","type":"bytes32"},{"internalType":"uint256","name":"_blockWait","type":"uint256"},{"internalType":"uint24","name":"_targetVotePpm","type":"uint24"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_description","type":"bytes32"},{"internalType":"bytes32[]","name":"_options","type":"bytes32[]"},{"internalType":"uint256","name":"_blockWait","type":"uint256"},{"internalType":"uint24","name":"_targetVotePpm","type":"uint24"}],"name":"proposeMulti","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIndex","type":"uint256"},{"internalType":"uint8","name":"_count","type":"uint8"}],"name":"scan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"vote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteCancel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"internalType":"uint256","name":"_optionIdx","type":"uint256"}],"name":"voteCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_optionIndex","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteOption","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_protectSupply","type":"bool"},{"internalType":"address","name":"_voterRegistry","type":"address"},{"internalType":"address","name":"_proposerRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_blockDeadline","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"voteTargetPpm","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"indexed":true,"internalType":"bool","name":"_cancelled","type":"bool"},{"indexed":true,"internalType":"bool","name":"_insufficient","type":"bool"},{"indexed":false,"internalType":"uint256","name":"_totalVote","type":"uint256"}],"name":"ProposalCompleted","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentProposal","outputs":[{"components":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"internalType":"bytes32[]","name":"options","type":"bytes32[]"},{"internalType":"uint256[]","name":"optionVotes","type":"uint256[]"},{"internalType":"uint256","name":"cancelVotes","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"blockDeadline","type":"uint256"},{"internalType":"uint24","name":"targetVotePpm","type":"uint24"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint8","name":"scanCursor","type":"uint8"}],"internalType":"struct ERC20Vote.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"internalType":"uint256","name":"_optionIdx","type":"uint256"}],"name":"getOption","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"getProposal","outputs":[{"components":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"internalType":"bytes32[]","name":"options","type":"bytes32[]"},{"internalType":"uint256[]","name":"optionVotes","type":"uint256[]"},{"internalType":"uint256","name":"cancelVotes","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"blockDeadline","type":"uint256"},{"internalType":"uint24","name":"targetVotePpm","type":"uint24"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint8","name":"scanCursor","type":"uint8"}],"internalType":"struct ERC20Vote.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"optionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_description","type":"bytes32"},{"internalType":"uint256","name":"_blockWait","type":"uint256"},{"internalType":"uint24","name":"_targetVotePpm","type":"uint24"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_description","type":"bytes32"},{"internalType":"bytes32[]","name":"_options","type":"bytes32[]"},{"internalType":"uint256","name":"_blockWait","type":"uint256"},{"internalType":"uint24","name":"_targetVotePpm","type":"uint24"}],"name":"proposeMulti","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIndex","type":"uint256"},{"internalType":"uint8","name":"_count","type":"uint8"}],"name":"scan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"vote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteCancel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"internalType":"uint256","name":"_optionIdx","type":"uint256"}],"name":"voteCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_optionIndex","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteOption","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/python/evm_tokenvote/data/Voter.metadata.json b/python/evm_tokenvote/data/Voter.metadata.json @@ -1 +1 @@ -{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_voterRegistry","type":"address"},{"internalType":"address","name":"_proposerRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_blockDeadline","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"voteTargetPpm","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"indexed":true,"internalType":"bool","name":"_cancelled","type":"bool"},{"indexed":true,"internalType":"bool","name":"_insufficient","type":"bool"},{"indexed":false,"internalType":"uint256","name":"_totalVote","type":"uint256"}],"name":"ProposalCompleted","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentProposal","outputs":[{"components":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"internalType":"bytes32[]","name":"options","type":"bytes32[]"},{"internalType":"uint256[]","name":"optionVotes","type":"uint256[]"},{"internalType":"uint256","name":"cancelVotes","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"blockDeadline","type":"uint256"},{"internalType":"uint24","name":"targetVotePpm","type":"uint24"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint8","name":"scanCursor","type":"uint8"}],"internalType":"struct ERC20Vote.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"internalType":"uint256","name":"_optionIdx","type":"uint256"}],"name":"getOption","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"getProposal","outputs":[{"components":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"internalType":"bytes32[]","name":"options","type":"bytes32[]"},{"internalType":"uint256[]","name":"optionVotes","type":"uint256[]"},{"internalType":"uint256","name":"cancelVotes","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"blockDeadline","type":"uint256"},{"internalType":"uint24","name":"targetVotePpm","type":"uint24"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint8","name":"scanCursor","type":"uint8"}],"internalType":"struct ERC20Vote.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"optionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_description","type":"bytes32"},{"internalType":"uint256","name":"_blockWait","type":"uint256"},{"internalType":"uint24","name":"_targetVotePpm","type":"uint24"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_description","type":"bytes32"},{"internalType":"bytes32[]","name":"_options","type":"bytes32[]"},{"internalType":"uint256","name":"_blockWait","type":"uint256"},{"internalType":"uint24","name":"_targetVotePpm","type":"uint24"}],"name":"proposeMulti","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIndex","type":"uint256"},{"internalType":"uint8","name":"_count","type":"uint8"}],"name":"scan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"vote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteCancel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"internalType":"uint256","name":"_optionIdx","type":"uint256"}],"name":"voteCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_optionIndex","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteOption","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"Voter.sol":"ERC20Vote"},"evmVersion":"byzantium","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"Voter.sol":{"keccak256":"0xf65cf2af03b63a8e215dbc5ebc77f5750ba634c7c99f015cb1a1e46b7ec02047","license":"AGPL-3.0-or-later","urls":["bzz-raw://d113abcfa639a671e9870dc517900e8faa26e3075f72597a6488b49bf7271c59","dweb:/ipfs/QmRzp6MDLeem3WFdzVZjAwojqabGWPoJPdBWuM8oo5CGxj"]}},"version":1} +{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_protectSupply","type":"bool"},{"internalType":"address","name":"_voterRegistry","type":"address"},{"internalType":"address","name":"_proposerRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_blockDeadline","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"voteTargetPpm","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"indexed":true,"internalType":"bool","name":"_cancelled","type":"bool"},{"indexed":true,"internalType":"bool","name":"_insufficient","type":"bool"},{"indexed":false,"internalType":"uint256","name":"_totalVote","type":"uint256"}],"name":"ProposalCompleted","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentProposal","outputs":[{"components":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"internalType":"bytes32[]","name":"options","type":"bytes32[]"},{"internalType":"uint256[]","name":"optionVotes","type":"uint256[]"},{"internalType":"uint256","name":"cancelVotes","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"blockDeadline","type":"uint256"},{"internalType":"uint24","name":"targetVotePpm","type":"uint24"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint8","name":"scanCursor","type":"uint8"}],"internalType":"struct ERC20Vote.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"internalType":"uint256","name":"_optionIdx","type":"uint256"}],"name":"getOption","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"getProposal","outputs":[{"components":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"internalType":"bytes32[]","name":"options","type":"bytes32[]"},{"internalType":"uint256[]","name":"optionVotes","type":"uint256[]"},{"internalType":"uint256","name":"cancelVotes","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"blockDeadline","type":"uint256"},{"internalType":"uint24","name":"targetVotePpm","type":"uint24"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint8","name":"scanCursor","type":"uint8"}],"internalType":"struct ERC20Vote.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"}],"name":"optionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_description","type":"bytes32"},{"internalType":"uint256","name":"_blockWait","type":"uint256"},{"internalType":"uint24","name":"_targetVotePpm","type":"uint24"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_description","type":"bytes32"},{"internalType":"bytes32[]","name":"_options","type":"bytes32[]"},{"internalType":"uint256","name":"_blockWait","type":"uint256"},{"internalType":"uint24","name":"_targetVotePpm","type":"uint24"}],"name":"proposeMulti","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIndex","type":"uint256"},{"internalType":"uint8","name":"_count","type":"uint8"}],"name":"scan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"vote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteCancel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_proposalIdx","type":"uint256"},{"internalType":"uint256","name":"_optionIdx","type":"uint256"}],"name":"voteCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_optionIndex","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteOption","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"Voter.sol":"ERC20Vote"},"evmVersion":"byzantium","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"Voter.sol":{"keccak256":"0x1d8415b9f6f62a4660a460329cef3f2409fdfa86529878fc0f7638851b5090e9","license":"AGPL-3.0-or-later","urls":["bzz-raw://1ad07818783e3662d1a545ac92aa9f8c8842815d4737de1ead6bc10b5f1d6200","dweb:/ipfs/QmX6iWf8TBL1gwqQUYgG2DBoVwpmceZUaay5HNPCVkLUbE"]}},"version":1} diff --git a/python/evm_tokenvote/unittest/base.py b/python/evm_tokenvote/unittest/base.py @@ -48,6 +48,8 @@ class TestEvmVoteAccounts(TestGiftableToken): self.supply = int(r, 16) self.assertGreater(self.supply, 0) + self.token_address = self.address + class TestEvmVote(TestEvmVoteAccounts): @@ -88,8 +90,6 @@ class TestEvmVoteRegistry(TestEvmVoteAccounts): def setUp(self): super(TestEvmVoteRegistry, self).setUp() - self.token_address = self.address - nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) c = AccountRegistry(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) (tx_hash, o) = c.constructor(self.accounts[0]) diff --git a/python/evm_tokenvote/voter.py b/python/evm_tokenvote/voter.py @@ -64,15 +64,15 @@ class Voter(TxFactory): __abi = None __bytecode = None - def constructor(self, sender_address, token_address, voter_registry_address=None, proposer_registry_address=None, tx_format=TxFormat.JSONRPC, version=None): - code = self.cargs(token_address, voter_registry_address=voter_registry_address, proposer_registry_address=proposer_registry_address) + def constructor(self, sender_address, token_address, protect_supply=False, voter_registry_address=None, proposer_registry_address=None, tx_format=TxFormat.JSONRPC, version=None): + code = self.cargs(token_address, protect_supply=protect_supply, voter_registry_address=voter_registry_address, proposer_registry_address=proposer_registry_address) tx = self.template(sender_address, None, use_nonce=True) tx = self.set_code(tx, code) return self.finalize(tx, tx_format) @staticmethod - def cargs(token_address, voter_registry_address=None, proposer_registry_address=None, version=None): + def cargs(token_address, protect_supply=False, voter_registry_address=None, proposer_registry_address=None, version=None): if voter_registry_address == None: voter_registry_address = ZERO_ADDRESS if proposer_registry_address == None: @@ -82,6 +82,7 @@ class Voter(TxFactory): code = Voter.bytecode(version=version) enc = ABIContractEncoder() enc.address(token_address) + enc.bool(protect_supply) enc.address(voter_registry_address) enc.address(proposer_registry_address) args = enc.get() diff --git a/python/tests/test_base.py b/python/tests/test_base.py @@ -239,7 +239,7 @@ class TestVoteBase(TestEvmVoteProposal): self.assertEqual(proposal.state & ProposalState.SUPPLYCHANGE, 0) - def test_proposal_invalid_supplychange(self): + def test_proposal_ok_supplychange(self): nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.alice, 1) @@ -266,6 +266,7 @@ class TestVoteBase(TestEvmVoteProposal): proposal = c.parse_proposal(r) self.assertEqual(proposal.state & ProposalState.FINAL, ProposalState.FINAL) self.assertEqual(proposal.state & ProposalState.SUPPLYCHANGE, ProposalState.SUPPLYCHANGE) + self.assertEqual(proposal.state & ProposalState.CANCELLED, 0) if __name__ == '__main__': diff --git a/python/tests/test_protect.py b/python/tests/test_protect.py @@ -0,0 +1,70 @@ +# standard imports +import unittest +import logging +import os +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.tx import receipt +from chainlib.eth.block import block_latest +from chainlib.eth.address import to_checksum_address +from hexathon import same as same_hex +from eth_erc20 import ERC20 +from giftable_erc20_token import GiftableToken + +# local imports +from evm_tokenvote.unittest import TestEvmVoteAccounts +from evm_tokenvote.unittest.base import hash_of_foo +from evm_tokenvote import Voter +from evm_tokenvote import ProposalState + + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +class TestVoteProtect(TestEvmVoteAccounts): + + def setUp(self): + super(TestVoteProtect, self).setUp() + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.constructor(self.accounts[0], self.token_address, protect_supply=True) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + self.voter_address = to_checksum_address(r['contract_address']) + logg.debug('published protected voter on address {} with hash {}'.format(self.voter_address, tx_hash)) + + + def test_propose(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.propose(self.voter_address, self.accounts[0], hash_of_foo, 100) + self.rpc.do(o) + + c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.alice, 1) + self.rpc.do(o) + + self.backend.mine_blocks(100) + + nonce_oracle = RPCNonceOracle(self.trent, conn=self.conn) + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 0) + self.rpc.do(o) + + (tx_hash, o) = c.finalize_vote(self.voter_address, self.trent) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) + r = self.rpc.do(o) + proposal = c.parse_proposal(r) + self.assertEqual(proposal.state & ProposalState.FINAL, ProposalState.FINAL) + self.assertEqual(proposal.state & ProposalState.SUPPLYCHANGE, ProposalState.SUPPLYCHANGE) + self.assertEqual(proposal.state & ProposalState.CANCELLED, ProposalState.CANCELLED) + + +if __name__ == '__main__': + unittest.main() diff --git a/solidity/Voter.sol b/solidity/Voter.sol @@ -6,14 +6,14 @@ pragma solidity ^0.8.0; // Description: Voting contract using ERC20 tokens as shares contract ERC20Vote { - uint8 constant STATE_INIT = 1; - uint8 constant STATE_FINAL = 2; - uint8 constant STATE_SCANNED = 4; - uint8 constant STATE_INSUFFICIENT = 8; - uint8 constant STATE_TIED = 16; - uint8 constant STATE_SUPPLYCHANGE = 32; - uint8 constant STATE_IMMEDIATE = 64; - uint8 constant STATE_CANCELLED = 128; + uint8 constant STATE_INIT = 1; // proposal has been initiated. + uint8 constant STATE_FINAL = 2; // proposal has been finalized. + uint8 constant STATE_SCANNED = 4; // proposal votes have been scanned (this can be done after finalization). + uint8 constant STATE_INSUFFICIENT = 8; // proposal did not attract minimum participation before deadline. + uint8 constant STATE_TIED = 16; // two or more proposal options have the same amount of votes. + uint8 constant STATE_SUPPLYCHANGE = 32; // supply changed while voting was underway. + uint8 constant STATE_IMMEDIATE = 64; // minimum participation was attained before deadline. + uint8 constant STATE_CANCELLED = 128; // vote to cancel the proposal has the majority. address public token; @@ -31,25 +31,44 @@ contract ERC20Vote { uint8 scanCursor; } + // sequential index of all added proposals. Proposal[] proposals; + + // optional access control registry of which addresses to allow voting. address voterRegistry; + + // optional access control registry of which addresses to allow adding proposals. address proposerRegistry; + // proposal currently being voted on (provided the proposal has INIT set). uint256 currentProposal; + // if set, the proposal will be cancelled with supply has been changed. + // The proposal will be marked accordingly to disambiguate the cancellation from a cancel vote. + bool protectSupply; + + // value of tokens held in escrow per account. mapping ( address => uint256 ) public balanceOf; - mapping ( address => uint256 ) proposalIdxLock; + // links escow to specific proposal, controls whether tokens can be withdrawn. + mapping ( address => uint256 ) proposalIdxLock; + + // a new proposal has been added to the proposals index. event ProposalAdded(uint256 indexed _blockDeadline, uint256 indexed voteTargetPpm, uint256 indexed _proposalIdx); + + // the current proposal has been finalized; whether successful, cancelled or insufficient vote. event ProposalCompleted(uint256 indexed _proposalIdx, bool indexed _cancelled, bool indexed _insufficient, uint256 _totalVote); - constructor(address _token, address _voterRegistry, address _proposerRegistry) { + // token must be specified. it is the caller's responsibility to ensure that the token has a value interface. + // if a registry is the zero-address, it will be deactivated. + constructor(address _token, bool _protectSupply, address _voterRegistry, address _proposerRegistry) { Proposal memory l_proposal; token = _token; voterRegistry = _voterRegistry; proposerRegistry = _proposerRegistry; proposals.push(l_proposal); currentProposal = 1; + protectSupply = _protectSupply; } // Propose a vote on the subject described by digest. @@ -330,8 +349,11 @@ contract ERC20Vote { } else if (l_supply != proposal.supply) { proposal.state |= STATE_SUPPLYCHANGE; proposal.state |= STATE_FINAL; - currentProposal += 1; - return 0; + if (protectSupply) { + currentProposal += 1; + proposal.state |= STATE_CANCELLED; + return 0; + } } return l_supply;