evm-tokenvote

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 412721a621d8679f16daa0e12e62246d8752ecdc
parent 8174db231d4beae2845e853a7c7822c2ecd833ea
Author: lash <dev@holbrook.no>
Date:   Sat,  6 May 2023 00:47:17 +0100

Add tests for (and correct) propose, vote, insufficient vote

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 | 40++++++++++++++++++++++++++++++++--------
Mpython/evm_tokenvote/voter.py | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Apython/run_tests.sh | 14++++++++++++++
Mpython/tests/test_base.py | 192++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Dsolidity/Vote_fail.sol | 319-------------------------------------------------------------------------------
Msolidity/Voter.sol | 35+++++++++++++++++++++++++----------
9 files changed, 311 insertions(+), 359 deletions(-)

diff --git a/python/evm_tokenvote/data/Voter.bin b/python/evm_tokenvote/data/Voter.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b506040516200282a3803806200282a83398181016040528101906200003791906200012a565b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505062000171565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000f282620000c5565b9050919050565b6200010481620000e5565b81146200011057600080fd5b50565b6000815190506200012481620000f9565b92915050565b60008060408385031215620001445762000143620000c0565b5b6000620001548582860162000113565b9250506020620001678582860162000113565b9150509250929050565b6126a980620001816000396000f3fe608060405234801561001057600080fd5b50600436106100bb576000357c010000000000000000000000000000000000000000000000000000000090048063b05c65ba11610083578063b05c65ba14610193578063b384abef146101c3578063ce746024146101f3578063e99a943e14610211578063fc0c546a14610241576100bb565b8063013cf08b146100c05780632b49d425146100f75780634bb278f31461011557806370a08231146101335780638bb5221314610163575b600080fd5b6100da60048036038101906100d5919061182f565b61025f565b6040516100ee9897969594939291906118ff565b60405180910390f35b6100ff610300565b60405161010c919061197d565b60405180910390f35b61011d610306565b60405161012a91906119b3565b60405180910390f35b61014d600480360381019061014891906119fa565b6104e8565b60405161015a919061197d565b60405180910390f35b61017d60048036038101906101789190611a53565b610500565b60405161018a91906119b3565b60405180910390f35b6101ad60048036038101906101a89190611c44565b61075c565b6040516101ba919061197d565b60405180910390f35b6101dd60048036038101906101d89190611cc7565b6109f8565b6040516101ea91906119b3565b60405180910390f35b6101fb610e58565b604051610208919061197d565b60405180910390f35b61022b60048036038101906102269190611d07565b6111e1565b604051610238919061197d565b60405180910390f35b6102496111fb565b6040516102569190611d5a565b60405180910390f35b6001818154811061026f57600080fd5b90600052602060002090600702016000915090508060000154908060030154908060040154908060050154908060060160009054906101000a900462ffffff16908060060160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060060160179054906101000a900460ff16908060060160189054906101000a900460ff16905088565b60035481565b60008060008060016003548154811061032257610321611d75565b5b90600052602060002090600702019250600060028460060160179054906101000a900460ff161660ff161461038c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038390611e01565b60405180910390fd5b600060048460060160179054906101000a900460ff161660ff16146103e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103dd90611e6d565b60405180910390fd5b60006103f18461121f565b0361040257600093505050506104e5565b60028360060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055506001600360008282546104459190611ebc565b92505081905550620f4240836004015461045f9190611ef0565b9150620f424083600301546104749190611ef0565b90508260060160009054906101000a900462ffffff1662ffffff16828261049b9190611f61565b10156104dd5760088360060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff160217905550600093505050506104e5565b600193505050505b90565b60046020528060005260406000206000915090505481565b60008060008060008060008060018a815481106105205761051f611d75565b5b906000526020600020906007020196504387600501541115610577576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e90611fde565b60405180910390fd5b600060048860060160179054906101000a900460ff161660ff1611156105a7576000975050505050505050610756565b8660060160189054906101000a900460ff169150866001018054905089836105cf9190611ffe565b60ff1611156105ee578187600101805490506105eb9190612033565b98505b81896105fa9190611ffe565b98508660060160179054906101000a900460ff1690508195505b8860ff168660ff1610156106a357866002018660ff168154811061063b5761063a611d75565b5b9060005260206000200154925060008311801561065757508383145b1561066757601081179050610681565b83831115610680578293508560ff169450601019811690505b5b60018261068e9190611ffe565b9150858061069b90612068565b965050610614565b818760060160186101000a81548160ff021916908360ff160217905550808760060160176101000a81548160ff021916908360ff16021790555086600101805490508760060160189054906101000a900460ff1660ff1610156107315760048760060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055505b600060048860060160179054906101000a900460ff161660ff16119750505050505050505b92915050565b600061076661169a565b6000806101008751106107ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a5906120dd565b60405180910390fd5b338360e0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505087836000018181525050868360200181905250848360c0019062ffffff16908162ffffff1681525050854361081b9190611ebc565b9050808360a00181815250506001805490509150600183610100019060ff16908160ff16815250506001839080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001019080519060200190610895929190611711565b5060408201518160020190805190602001906108b292919061175e565b50606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548162ffffff021916908362ffffff16021790555060e08201518160060160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160060160176101000a81548160ff021916908360ff1602179055506101208201518160060160186101000a81548160ff021916908360ff16021790555050506109ad6001838154811061099a57610999611d75565b5b906000526020600020906007020161121f565b836060018181525050818562ffffff16827f5a41400aa51d78e9e5ca645b0d045817eaa7d90e4344d773fdbe24ffb183d3ce60405160405180910390a4819350505050949350505050565b60008060006060610a083361147e565b600160035481548110610a1e57610a1d611d75565b5b906000526020600020906007020192506000610a398461121f565b03610a4a5760009350505050610e52565b43836005015410610a90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8790612149565b60405180910390fd5b6000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115610b5c57600354600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610b5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b52906121b5565b60405180910390fd5b5b82600101805490508610610ba5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9c90612221565b60405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16333087604051602401610bf1939291906122a0565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610c7b9190612348565b6000604051808303816000865af19150503d8060008114610cb8576040519150601f19603f3d011682016040523d82523d6000602084013e610cbd565b606091505b50809250819350505081610d06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cfd906123ab565b60405180910390fd5b80806020019051810190610d1a91906123f7565b915081610d5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5390612470565b60405180910390fd5b600354600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555084600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610df19190611ebc565b9250508190555084836004016000828254610e0c9190611ebc565b9250508190555084836002018781548110610e2a57610e29611d75565b5b906000526020600020016000828254610e439190611ebc565b92505081905550600193505050505b92915050565b600080600060606000600160035481548110610e7757610e76611d75565b5b90600052602060002090600702019350600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600354600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403610f985743846005015411610f7b57600060028560060160179054906101000a900460ff161660ff1614610f76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6d90611fde565b60405180910390fd5b610f97565b80846004016000828254610f8f9190612490565b925050819055505b5b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16338260405160240161106c9291906124c4565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516110f69190612348565b6000604051808303816000865af19150503d8060008114611133576040519150601f19603f3d011682016040523d82523d6000602084013e611138565b606091505b50809350819450505082611181576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611178906123ab565b60405180910390fd5b8180602001905181019061119591906123f7565b9250826111d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ce90612470565b60405180910390fd5b8094505050505090565b600060606111f18582868661075c565b9150509392505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080606060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f18160ddd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516112ee9190612348565b6000604051808303816000865af19150503d806000811461132b576040519150601f19603f3d011682016040523d82523d6000602084013e611330565b606091505b50809350819450505082611379576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611370906123ab565b60405180910390fd5b8180602001905181019061138d9190612502565b9050600081116113d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c99061257b565b60405180910390fd5b60008560030154036113ec57808560030181905550611472565b60208560060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060028560060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060016003600082825461145f9190611ebc565b9250508190555060009350505050611479565b8093505050505b919050565b60006060600073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036114df575050611697565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16836040516024016115299190611d5a565b6040516020818303038152906040527f3ef25013000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516115b39190612348565b6000604051808303816000865af19150503d80600081146115f0576040519150601f19603f3d011682016040523d82523d6000602084013e6115f5565b606091505b5080925081935050508161163e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611635906125e7565b60405180910390fd5b8080602001905181019061165291906123f7565b915081611694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168b90612653565b60405180910390fd5b50505b50565b604051806101400160405280600080191681526020016060815260200160608152602001600081526020016000815260200160008152602001600062ffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b82805482825590600052602060002090810192821561174d579160200282015b8281111561174c578251825591602001919060010190611731565b5b50905061175a91906117ab565b5090565b82805482825590600052602060002090810192821561179a579160200282015b8281111561179957825182559160200191906001019061177e565b5b5090506117a791906117c8565b5090565b5b808211156117c45760008160009055506001016117ac565b5090565b5b808211156117e15760008160009055506001016117c9565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61180c816117f9565b811461181757600080fd5b50565b60008135905061182981611803565b92915050565b600060208284031215611845576118446117ef565b5b60006118538482850161181a565b91505092915050565b6000819050919050565b61186f8161185c565b82525050565b61187e816117f9565b82525050565b600062ffffff82169050919050565b61189c81611884565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006118cd826118a2565b9050919050565b6118dd816118c2565b82525050565b600060ff82169050919050565b6118f9816118e3565b82525050565b600061010082019050611915600083018b611866565b611922602083018a611875565b61192f6040830189611875565b61193c6060830188611875565b6119496080830187611893565b61195660a08301866118d4565b61196360c08301856118f0565b61197060e08301846118f0565b9998505050505050505050565b60006020820190506119926000830184611875565b92915050565b60008115159050919050565b6119ad81611998565b82525050565b60006020820190506119c860008301846119a4565b92915050565b6119d7816118c2565b81146119e257600080fd5b50565b6000813590506119f4816119ce565b92915050565b600060208284031215611a1057611a0f6117ef565b5b6000611a1e848285016119e5565b91505092915050565b611a30816118e3565b8114611a3b57600080fd5b50565b600081359050611a4d81611a27565b92915050565b60008060408385031215611a6a57611a696117ef565b5b6000611a788582860161181a565b9250506020611a8985828601611a3e565b9150509250929050565b611a9c8161185c565b8114611aa757600080fd5b50565b600081359050611ab981611a93565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611b0d82611ac4565b810181811067ffffffffffffffff82111715611b2c57611b2b611ad5565b5b80604052505050565b6000611b3f6117e5565b9050611b4b8282611b04565b919050565b600067ffffffffffffffff821115611b6b57611b6a611ad5565b5b602082029050602081019050919050565b600080fd5b6000611b94611b8f84611b50565b611b35565b90508083825260208201905060208402830185811115611bb757611bb6611b7c565b5b835b81811015611be05780611bcc8882611aaa565b845260208401935050602081019050611bb9565b5050509392505050565b600082601f830112611bff57611bfe611abf565b5b8135611c0f848260208601611b81565b91505092915050565b611c2181611884565b8114611c2c57600080fd5b50565b600081359050611c3e81611c18565b92915050565b60008060008060808587031215611c5e57611c5d6117ef565b5b6000611c6c87828801611aaa565b945050602085013567ffffffffffffffff811115611c8d57611c8c6117f4565b5b611c9987828801611bea565b9350506040611caa8782880161181a565b9250506060611cbb87828801611c2f565b91505092959194509250565b60008060408385031215611cde57611cdd6117ef565b5b6000611cec8582860161181a565b9250506020611cfd8582860161181a565b9150509250929050565b600080600060608486031215611d2057611d1f6117ef565b5b6000611d2e86828701611aaa565b9350506020611d3f8682870161181a565b9250506040611d5086828701611c2f565b9150509250925092565b6000602082019050611d6f60008301846118d4565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082825260208201905092915050565b7f4552525f414c52454144595f53544154455f46494e414c000000000000000000600082015250565b6000611deb601783611da4565b9150611df682611db5565b602082019050919050565b60006020820190508181036000830152611e1a81611dde565b9050919050565b7f4552525f5343414e5f4649525354000000000000000000000000000000000000600082015250565b6000611e57600e83611da4565b9150611e6282611e21565b602082019050919050565b60006020820190508181036000830152611e8681611e4a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611ec7826117f9565b9150611ed2836117f9565b9250828201905080821115611eea57611ee9611e8d565b5b92915050565b6000611efb826117f9565b9150611f06836117f9565b9250828202611f14816117f9565b91508282048414831517611f2b57611f2a611e8d565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000611f6c826117f9565b9150611f77836117f9565b925082611f8757611f86611f32565b5b828204905092915050565b7f4552525f5052454d415455524500000000000000000000000000000000000000600082015250565b6000611fc8600d83611da4565b9150611fd382611f92565b602082019050919050565b60006020820190508181036000830152611ff781611fbb565b9050919050565b6000612009826118e3565b9150612014836118e3565b9250828201905060ff81111561202d5761202c611e8d565b5b92915050565b600061203e826118e3565b9150612049836118e3565b9250828203905060ff81111561206257612061611e8d565b5b92915050565b6000612073826118e3565b915060ff820361208657612085611e8d565b5b600182019050919050565b7f4552525f544f4f5f4d414e595f4f5054494f4e53000000000000000000000000600082015250565b60006120c7601483611da4565b91506120d282612091565b602082019050919050565b600060208201905081810360008301526120f6816120ba565b9050919050565b7f4552525f444541444c494e450000000000000000000000000000000000000000600082015250565b6000612133600c83611da4565b915061213e826120fd565b602082019050919050565b6000602082019050818103600083015261216281612126565b9050919050565b7f4552525f5245434f5645525f4649525354000000000000000000000000000000600082015250565b600061219f601183611da4565b91506121aa82612169565b602082019050919050565b600060208201905081810360008301526121ce81612192565b9050919050565b7f4552525f4f5054494f4e5f494e56414c49440000000000000000000000000000600082015250565b600061220b601283611da4565b9150612216826121d5565b602082019050919050565b6000602082019050818103600083015261223a816121fe565b9050919050565b6000819050919050565b600061226661226161225c846118a2565b612241565b6118a2565b9050919050565b60006122788261224b565b9050919050565b600061228a8261226d565b9050919050565b61229a8161227f565b82525050565b60006060820190506122b560008301866118d4565b6122c26020830185612291565b6122cf6040830184611875565b949350505050565b600081519050919050565b600081905092915050565b60005b8381101561230b5780820151818401526020810190506122f0565b60008484015250505050565b6000612322826122d7565b61232c81856122e2565b935061233c8185602086016122ed565b80840191505092915050565b60006123548284612317565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b6000612395600983611da4565b91506123a08261235f565b602082019050919050565b600060208201905081810360008301526123c481612388565b9050919050565b6123d481611998565b81146123df57600080fd5b50565b6000815190506123f1816123cb565b92915050565b60006020828403121561240d5761240c6117ef565b5b600061241b848285016123e2565b91505092915050565b7f4552525f5452414e534645520000000000000000000000000000000000000000600082015250565b600061245a600c83611da4565b915061246582612424565b602082019050919050565b600060208201905081810360008301526124898161244d565b9050919050565b600061249b826117f9565b91506124a6836117f9565b92508282039050818111156124be576124bd611e8d565b5b92915050565b60006040820190506124d960008301856118d4565b6124e66020830184611875565b9392505050565b6000815190506124fc81611803565b92915050565b600060208284031215612518576125176117ef565b5b6000612526848285016124ed565b91505092915050565b7f4552525f5a45524f5f535550504c590000000000000000000000000000000000600082015250565b6000612565600f83611da4565b91506125708261252f565b602082019050919050565b6000602082019050818103600083015261259481612558565b9050919050565b7f4552525f52454749535452590000000000000000000000000000000000000000600082015250565b60006125d1600c83611da4565b91506125dc8261259b565b602082019050919050565b60006020820190508181036000830152612600816125c4565b9050919050565b7f4552525f554e415554485f4143434f554e540000000000000000000000000000600082015250565b600061263d601283611da4565b915061264882612607565b602082019050919050565b6000602082019050818103600083015261266c81612630565b905091905056fea264697066735822122047d41ca0f2e88e8d08bcf196d122a8378c2e0035d55b74c163578c19415d2c6f64736f6c63430008130033 -\ No newline at end of file +60806040523480156200001157600080fd5b50604051620029a7380380620029a783398181016040528101906200003791906200012a565b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505062000171565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000f282620000c5565b9050919050565b6200010481620000e5565b81146200011057600080fd5b50565b6000815190506200012481620000f9565b92915050565b60008060408385031215620001445762000143620000c0565b5b6000620001548582860162000113565b9250506020620001678582860162000113565b9150509250929050565b61282680620001816000396000f3fe608060405234801561001057600080fd5b50600436106100c6576000357c01000000000000000000000000000000000000000000000000000000009004806370a082311161008e57806370a082311461019e5780638bb52213146101ce578063b05c65ba146101fe578063ce7460241461022e578063e99a943e1461024c578063fc0c546a1461027c576100c6565b80630121b93f146100cb578063013cf08b146100fb5780632b49d425146101325780634bb278f314610150578063509bd3371461016e575b600080fd5b6100e560048036038101906100e09190611940565b61029a565b6040516100f29190611988565b60405180910390f35b61011560048036038101906101109190611940565b6102ae565b604051610129989796959493929190611a46565b60405180910390f35b61013a61034f565b6040516101479190611ac4565b60405180910390f35b610158610355565b6040516101659190611988565b60405180910390f35b61018860048036038101906101839190611adf565b610522565b6040516101959190611988565b60405180910390f35b6101b860048036038101906101b39190611b4b565b6109fe565b6040516101c59190611ac4565b60405180910390f35b6101e860048036038101906101e39190611ba4565b610a16565b6040516101f59190611988565b60405180910390f35b61021860048036038101906102139190611d95565b610cc1565b6040516102259190611ac4565b60405180910390f35b610236610f5d565b6040516102439190611ac4565b60405180910390f35b61026660048036038101906102619190611e18565b6112e6565b6040516102739190611ac4565b60405180910390f35b610284611300565b6040516102919190611e6b565b60405180910390f35b60006102a7600083610522565b9050919050565b600181815481106102be57600080fd5b90600052602060002090600702016000915090508060000154908060030154908060040154908060050154908060060160009054906101000a900462ffffff16908060060160039054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060060160179054906101000a900460ff16908060060160189054906101000a900460ff16905088565b60035481565b60008060006001600354815481106103705761036f611e86565b5b90600052602060002090600702019150600060028360060160179054906101000a900460ff161660ff16146103da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d190611f12565b60405180910390fd5b600060048360060160179054906101000a900460ff161660ff1611610434576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042b90611f7e565b60405180910390fd5b600061043f83611324565b0361044f5760009250505061051f565b60028260060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055506001600360008282546104929190611fcd565b92505081905550620f424082600401546104ac9190612001565b90508160060160009054906101000a900462ffffff1662ffffff168260030154826104d79190612072565b10156105185760088260060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060009250505061051f565b6001925050505b90565b600080600060606105323361158f565b60016003548154811061054857610547611e86565b5b90600052602060002090600702019250600060018460060160179054906101000a900460ff161660ff16116105b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a9906120ef565b60405180910390fd5b60006105bd84611324565b036105ce57600093505050506109f8565b43836005015411610614576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060b9061215b565b60405180910390fd5b6000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411156106e057600354600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146106df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d6906121c7565b60405180910390fd5b5b60008360010180549050111561073a5782600101805490508610610739576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073090612233565b60405180910390fd5b5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16333087604051602401610786939291906122b2565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610810919061235a565b6000604051808303816000865af19150503d806000811461084d576040519150601f19603f3d011682016040523d82523d6000602084013e610852565b606091505b5080925081935050508161089b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610892906123bd565b60405180910390fd5b808060200190518101906108af9190612409565b9150816108f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e890612482565b60405180910390fd5b600354600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555084600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546109869190611fcd565b92505081905550848360040160008282546109a19190611fcd565b925050819055506000836001018054905011156109f057848360020187815481106109cf576109ce611e86565b5b9060005260206000200160008282546109e89190611fcd565b925050819055505b600193505050505b92915050565b60046020528060005260406000206000915090505481565b60008060008060008060008060018a81548110610a3657610a35611e86565b5b906000526020600020906007020196504387600501541115610a8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a84906124ee565b60405180910390fd5b600060048860060160179054906101000a900460ff161660ff161115610abd576000975050505050505050610cbb565b6000876001018054905003610b0c5760048760060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055506001975050505050505050610cbb565b8660060160189054906101000a900460ff16915086600101805490508983610b34919061250e565b60ff161115610b5357818760010180549050610b509190612543565b98505b8189610b5f919061250e565b98508660060160179054906101000a900460ff1690508195505b8860ff168660ff161015610c0857866002018660ff1681548110610ba057610b9f611e86565b5b90600052602060002001549250600083118015610bbc57508383145b15610bcc57601081179050610be6565b83831115610be5578293508560ff169450601019811690505b5b600182610bf3919061250e565b91508580610c0090612578565b965050610b79565b818760060160186101000a81548160ff021916908360ff160217905550808760060160176101000a81548160ff021916908360ff16021790555086600101805490508760060160189054906101000a900460ff1660ff161015610c965760048760060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff1602179055505b600060048860060160179054906101000a900460ff161660ff16119750505050505050505b92915050565b6000610ccb6117ab565b600080610100875110610d13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0a906125ed565b60405180910390fd5b338360e0019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505087836000018181525050868360200181905250848360c0019062ffffff16908162ffffff16815250508543610d809190611fcd565b9050808360a00181815250506001805490509150600183610100019060ff16908160ff16815250506001839080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001019080519060200190610dfa929190611822565b506040820151816002019080519060200190610e1792919061186f565b50606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548162ffffff021916908362ffffff16021790555060e08201518160060160036101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160060160176101000a81548160ff021916908360ff1602179055506101208201518160060160186101000a81548160ff021916908360ff1602179055505050610f1260018381548110610eff57610efe611e86565b5b9060005260206000209060070201611324565b836060018181525050818562ffffff16827f5a41400aa51d78e9e5ca645b0d045817eaa7d90e4344d773fdbe24ffb183d3ce60405160405180910390a4819350505050949350505050565b600080600060606000600160035481548110610f7c57610f7b611e86565b5b90600052602060002090600702019350600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600354600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540361109d574384600501541161108057600060028560060160179054906101000a900460ff161660ff161461107b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611072906124ee565b60405180910390fd5b61109c565b80846004016000828254611094919061260d565b925050819055505b5b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163382604051602401611171929190612641565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516111fb919061235a565b6000604051808303816000865af19150503d8060008114611238576040519150601f19603f3d011682016040523d82523d6000602084013e61123d565b606091505b50809350819450505082611286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127d906123bd565b60405180910390fd5b8180602001905181019061129a9190612409565b9250826112dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d390612482565b60405180910390fd5b8094505050505090565b600060606112f685828686610cc1565b9150509392505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080606060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f18160ddd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516113f3919061235a565b6000604051808303816000865af19150503d8060008114611430576040519150601f19603f3d011682016040523d82523d6000602084013e611435565b606091505b5080935081945050508261147e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611475906123bd565b60405180910390fd5b81806020019051810190611492919061267f565b9050600081116114d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ce906126f8565b60405180910390fd5b60008560030154036114f157808560030181905550611583565b846003015481146115825760208560060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060028560060160178282829054906101000a900460ff161792506101000a81548160ff021916908360ff16021790555060016003600082825461156f9190611fcd565b925050819055506000935050505061158a565b5b8093505050505b919050565b60006060600073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036115f05750506117a8565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360405160240161163a9190611e6b565b6040516020818303038152906040527f3ef25013000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516116c4919061235a565b6000604051808303816000865af19150503d8060008114611701576040519150601f19603f3d011682016040523d82523d6000602084013e611706565b606091505b5080925081935050508161174f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174690612764565b60405180910390fd5b808060200190518101906117639190612409565b9150816117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179c906127d0565b60405180910390fd5b50505b50565b604051806101400160405280600080191681526020016060815260200160608152602001600081526020016000815260200160008152602001600062ffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600060ff1681525090565b82805482825590600052602060002090810192821561185e579160200282015b8281111561185d578251825591602001919060010190611842565b5b50905061186b91906118bc565b5090565b8280548282559060005260206000209081019282156118ab579160200282015b828111156118aa57825182559160200191906001019061188f565b5b5090506118b891906118d9565b5090565b5b808211156118d55760008160009055506001016118bd565b5090565b5b808211156118f25760008160009055506001016118da565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61191d8161190a565b811461192857600080fd5b50565b60008135905061193a81611914565b92915050565b60006020828403121561195657611955611900565b5b60006119648482850161192b565b91505092915050565b60008115159050919050565b6119828161196d565b82525050565b600060208201905061199d6000830184611979565b92915050565b6000819050919050565b6119b6816119a3565b82525050565b6119c58161190a565b82525050565b600062ffffff82169050919050565b6119e3816119cb565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611a14826119e9565b9050919050565b611a2481611a09565b82525050565b600060ff82169050919050565b611a4081611a2a565b82525050565b600061010082019050611a5c600083018b6119ad565b611a69602083018a6119bc565b611a7660408301896119bc565b611a8360608301886119bc565b611a9060808301876119da565b611a9d60a0830186611a1b565b611aaa60c0830185611a37565b611ab760e0830184611a37565b9998505050505050505050565b6000602082019050611ad960008301846119bc565b92915050565b60008060408385031215611af657611af5611900565b5b6000611b048582860161192b565b9250506020611b158582860161192b565b9150509250929050565b611b2881611a09565b8114611b3357600080fd5b50565b600081359050611b4581611b1f565b92915050565b600060208284031215611b6157611b60611900565b5b6000611b6f84828501611b36565b91505092915050565b611b8181611a2a565b8114611b8c57600080fd5b50565b600081359050611b9e81611b78565b92915050565b60008060408385031215611bbb57611bba611900565b5b6000611bc98582860161192b565b9250506020611bda85828601611b8f565b9150509250929050565b611bed816119a3565b8114611bf857600080fd5b50565b600081359050611c0a81611be4565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611c5e82611c15565b810181811067ffffffffffffffff82111715611c7d57611c7c611c26565b5b80604052505050565b6000611c906118f6565b9050611c9c8282611c55565b919050565b600067ffffffffffffffff821115611cbc57611cbb611c26565b5b602082029050602081019050919050565b600080fd5b6000611ce5611ce084611ca1565b611c86565b90508083825260208201905060208402830185811115611d0857611d07611ccd565b5b835b81811015611d315780611d1d8882611bfb565b845260208401935050602081019050611d0a565b5050509392505050565b600082601f830112611d5057611d4f611c10565b5b8135611d60848260208601611cd2565b91505092915050565b611d72816119cb565b8114611d7d57600080fd5b50565b600081359050611d8f81611d69565b92915050565b60008060008060808587031215611daf57611dae611900565b5b6000611dbd87828801611bfb565b945050602085013567ffffffffffffffff811115611dde57611ddd611905565b5b611dea87828801611d3b565b9350506040611dfb8782880161192b565b9250506060611e0c87828801611d80565b91505092959194509250565b600080600060608486031215611e3157611e30611900565b5b6000611e3f86828701611bfb565b9350506020611e508682870161192b565b9250506040611e6186828701611d80565b9150509250925092565b6000602082019050611e806000830184611a1b565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082825260208201905092915050565b7f4552525f414c52454144595f53544154455f46494e414c000000000000000000600082015250565b6000611efc601783611eb5565b9150611f0782611ec6565b602082019050919050565b60006020820190508181036000830152611f2b81611eef565b9050919050565b7f4552525f5343414e5f4649525354000000000000000000000000000000000000600082015250565b6000611f68600e83611eb5565b9150611f7382611f32565b602082019050919050565b60006020820190508181036000830152611f9781611f5b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fd88261190a565b9150611fe38361190a565b9250828201905080821115611ffb57611ffa611f9e565b5b92915050565b600061200c8261190a565b91506120178361190a565b92508282026120258161190a565b9150828204841483151761203c5761203b611f9e565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061207d8261190a565b91506120888361190a565b92508261209857612097612043565b5b828204905092915050565b7f4552525f50524f504f53414c5f494e4143544956450000000000000000000000600082015250565b60006120d9601583611eb5565b91506120e4826120a3565b602082019050919050565b60006020820190508181036000830152612108816120cc565b9050919050565b7f4552525f444541444c494e450000000000000000000000000000000000000000600082015250565b6000612145600c83611eb5565b91506121508261210f565b602082019050919050565b6000602082019050818103600083015261217481612138565b9050919050565b7f4552525f5245434f5645525f4649525354000000000000000000000000000000600082015250565b60006121b1601183611eb5565b91506121bc8261217b565b602082019050919050565b600060208201905081810360008301526121e0816121a4565b9050919050565b7f4552525f4f5054494f4e5f494e56414c49440000000000000000000000000000600082015250565b600061221d601283611eb5565b9150612228826121e7565b602082019050919050565b6000602082019050818103600083015261224c81612210565b9050919050565b6000819050919050565b600061227861227361226e846119e9565b612253565b6119e9565b9050919050565b600061228a8261225d565b9050919050565b600061229c8261227f565b9050919050565b6122ac81612291565b82525050565b60006060820190506122c76000830186611a1b565b6122d460208301856122a3565b6122e160408301846119bc565b949350505050565b600081519050919050565b600081905092915050565b60005b8381101561231d578082015181840152602081019050612302565b60008484015250505050565b6000612334826122e9565b61233e81856122f4565b935061234e8185602086016122ff565b80840191505092915050565b60006123668284612329565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b60006123a7600983611eb5565b91506123b282612371565b602082019050919050565b600060208201905081810360008301526123d68161239a565b9050919050565b6123e68161196d565b81146123f157600080fd5b50565b600081519050612403816123dd565b92915050565b60006020828403121561241f5761241e611900565b5b600061242d848285016123f4565b91505092915050565b7f4552525f5452414e534645520000000000000000000000000000000000000000600082015250565b600061246c600c83611eb5565b915061247782612436565b602082019050919050565b6000602082019050818103600083015261249b8161245f565b9050919050565b7f4552525f5052454d415455524500000000000000000000000000000000000000600082015250565b60006124d8600d83611eb5565b91506124e3826124a2565b602082019050919050565b60006020820190508181036000830152612507816124cb565b9050919050565b600061251982611a2a565b915061252483611a2a565b9250828201905060ff81111561253d5761253c611f9e565b5b92915050565b600061254e82611a2a565b915061255983611a2a565b9250828203905060ff81111561257257612571611f9e565b5b92915050565b600061258382611a2a565b915060ff820361259657612595611f9e565b5b600182019050919050565b7f4552525f544f4f5f4d414e595f4f5054494f4e53000000000000000000000000600082015250565b60006125d7601483611eb5565b91506125e2826125a1565b602082019050919050565b60006020820190508181036000830152612606816125ca565b9050919050565b60006126188261190a565b91506126238361190a565b925082820390508181111561263b5761263a611f9e565b5b92915050565b60006040820190506126566000830185611a1b565b61266360208301846119bc565b9392505050565b60008151905061267981611914565b92915050565b60006020828403121561269557612694611900565b5b60006126a38482850161266a565b91505092915050565b7f4552525f5a45524f5f535550504c590000000000000000000000000000000000600082015250565b60006126e2600f83611eb5565b91506126ed826126ac565b602082019050919050565b60006020820190508181036000830152612711816126d5565b9050919050565b7f4552525f52454749535452590000000000000000000000000000000000000000600082015250565b600061274e600c83611eb5565b915061275982612718565b602082019050919050565b6000602082019050818103600083015261277d81612741565b9050919050565b7f4552525f554e415554485f4143434f554e540000000000000000000000000000600082015250565b60006127ba601283611eb5565b91506127c582612784565b602082019050919050565b600060208201905081810360008301526127e9816127ad565b905091905056fea26469706673582212204a1fb70284bfdf4ad9631173605d58e0df3befbd78bf87ff869adc7007dfe1f864736f6c63430008130033 +\ 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":"_accountsRegistry","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"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"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"}],"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":[],"name":"recover","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":"_optionIndex","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"vote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_accountsRegistry","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"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"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"}],"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":[],"name":"recover","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":"_optionIndex","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteOption","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_accountsRegistry","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"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"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"}],"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":[],"name":"recover","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":"_optionIndex","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"vote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"0xb8270f6a79fdead93f5f83c67e3de1fe69aee6316d697a327fff692c10226e41","license":"AGPL-3.0-or-later","urls":["bzz-raw://2b44be01e24d05c3a6e51a78adfb4b6e04fdbc81a2003bfedf3e7ac5528e9266","dweb:/ipfs/QmVY4XtyfNb42Pt1xZ1z3EFYAh7qyscmfWDhEuWKWY44Jd"]}},"version":1} +{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_accountsRegistry","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"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"bytes32","name":"description","type":"bytes32"},{"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"}],"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":[],"name":"recover","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":"_optionIndex","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"voteOption","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"0xdc68a926a68251e02bec8cf1383a18dbbdf8139810b434bea29bbce5784fe92c","license":"AGPL-3.0-or-later","urls":["bzz-raw://17b88e080199bdfd6822168cc27604e85db9251d67a3932457e168811b9a61ca","dweb:/ipfs/QmXmcsFydnHsLW13xp8Arn7BKXB4tRXgLttRiwGhwdSs2g"]}},"version":1} diff --git a/python/evm_tokenvote/unittest/base.py b/python/evm_tokenvote/unittest/base.py @@ -8,14 +8,18 @@ from chainlib.connection import RPCConnection from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.tx import receipt from chainlib.eth.address import to_checksum_address +from giftable_erc20_token.unittest import TestGiftableToken +#from giftable_erc20_token import GiftableToken +from eth_erc20 import ERC20 +from chainlib.eth.block import block_latest # local imports -from eth_erc20 import ERC20 -from giftable_erc20_token.unittest import TestGiftableToken from evm_tokenvote import Voter logg = logging.getLogger(__name__) +hash_of_foo = '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae' + class TestEvmVote(TestGiftableToken): @@ -23,6 +27,15 @@ class TestEvmVote(TestGiftableToken): def setUp(self): super(TestEvmVote, self).setUp() + + self.alice = self.accounts[1] + self.bob = self.accounts[2] + self.carol = self.accounts[3] + self.dave = self.accounts[4] + self.trent = self.accounts[5] + self.mallory = self.accounts[8] + self.ivan = self.accounts[9] + self.conn = RPCConnection.connect(self.chain_spec, 'default') c = ERC20(self.chain_spec) @@ -30,7 +43,7 @@ class TestEvmVote(TestGiftableToken): r = self.rpc.do(o) self.supply = int(r, 16) self.assertGreater(self.supply, 0) - + 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.address) @@ -41,8 +54,19 @@ class TestEvmVote(TestGiftableToken): self.voter_address = to_checksum_address(r['contract_address']) logg.debug('published voter on address {} with hash {}'.format(self.voter_address, tx_hash)) - self.alice = self.accounts[1] - self.bob = self.accounts[2] - self.carol = self.accounts[3] - self.dave = self.accounts[4] - self.mallory = self.accounts[8] + +class TestEvmVoteProposal(TestEvmVote): + + def setUp(self): + super(TestEvmVoteProposal, self).setUp() + description = hash_of_foo + nonce_oracle = RPCNonceOracle(self.ivan, conn=self.conn) + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.propose(self.voter_address, self.ivan, description, 100) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + o = block_latest() + self.proposal_block_height = self.rpc.do(o) diff --git a/python/evm_tokenvote/voter.py b/python/evm_tokenvote/voter.py @@ -53,7 +53,7 @@ class Proposal: def __str__(self): - return "proposal with description: " + self.description_digest + return "proposal description {} total {} supply {}".format(self.description_digest, self.total, self.supply) class Voter(TxFactory): @@ -125,6 +125,49 @@ class Voter(TxFactory): return tx + def vote(self, contract_address, sender_address, value, option=None, tx_format=TxFormat.JSONRPC, id_generator=None): + enc = ABIContractEncoder() + if option == None: + enc.method('vote') + enc.typ(ABIContractType.UINT256) + else: + enc.method('voteOption') + enc.typ(ABIContractType.UINT256) + enc.typ(ABIContractType.UINT256) + if option != None: + enc.uint256(option) + enc.uint256(value) + data = add_0x(enc.get()) + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format, id_generator=id_generator) + return tx + + + def scan(self, contract_address, sender_address, proposal_index, count, tx_format=TxFormat.JSONRPC, id_generator=None): + enc = ABIContractEncoder() + enc.method('scan') + enc.typ(ABIContractType.UINT256) + enc.typ(ABIContractType.UINT8) + enc.uint256(proposal_index) + enc.uintn(count, 8) + data = add_0x(enc.get()) + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format, id_generator=id_generator) + return tx + + + def finalize_vote(self, contract_address, sender_address, tx_format=TxFormat.JSONRPC, id_generator=None): + enc = ABIContractEncoder() + enc.method('finalize') + data = add_0x(enc.get()) + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format, id_generator=id_generator) + return tx + + def get_proposal(self, contract_address, proposal_idx, sender_address=ZERO_ADDRESS, id_generator=None): j = JSONRPCRequest(id_generator) o = j.template() @@ -142,6 +185,22 @@ class Voter(TxFactory): return o + def current_proposal_idx(self, contract_address, sender_address=ZERO_ADDRESS, id_generator=None): + j = JSONRPCRequest(id_generator) + o = j.template() + o['method'] = 'eth_call' + enc = ABIContractEncoder() + enc.method('currentProposal') + data = add_0x(enc.get()) + tx = self.template(sender_address, contract_address) + tx = self.set_code(tx, data) + o['params'].append(self.normalize(tx)) + o['params'].append('latest') + o = j.finalize(o) + return o + + + @classmethod def parse_proposal(self, v, serial=None): v = strip_0x(v) @@ -173,7 +232,6 @@ class Voter(TxFactory): dec.val(v[cursor:cursor+64]) r = dec.get() - logg.debug('rrr {}'.format(r)) o = Proposal(r[0], supply=r[1], total=r[2], diff --git a/python/run_tests.sh b/python/run_tests.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -a +set -e +set -x +default_pythonpath=$PYTHONPATH:. +export PYTHONPATH=${default_pythonpath:-.} +>&2 echo using pythonpath $PYTHONPATH +for f in `ls tests/*.py`; do + python $f +done +set +x +set +e +set +a diff --git a/python/tests/test_base.py b/python/tests/test_base.py @@ -5,11 +5,12 @@ import os from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.tx import receipt from chainlib.eth.block import block_latest -from chainlib.eth.block import block_by_number from hexathon import same as same_hex +from eth_erc20 import ERC20 # local imports -from evm_tokenvote.unittest import TestEvmVote +from evm_tokenvote.unittest import TestEvmVoteProposal +from evm_tokenvote.unittest.base import hash_of_foo from evm_tokenvote import Voter from evm_tokenvote import ProposalState @@ -17,35 +18,194 @@ from evm_tokenvote import ProposalState logging.basicConfig(level=logging.DEBUG) logg = logging.getLogger() -hash_of_foo = '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae' - -class TestVoteBase(TestEvmVote): +class TestVoteBase(TestEvmVoteProposal): def test_propose(self): - description = hash_of_foo - nonce_oracle = RPCNonceOracle(self.accounts[1], conn=self.conn) + c = Voter(self.chain_spec) + o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) + r = self.rpc.do(o) + proposal = c.parse_proposal(r) + self.assertTrue(same_hex(proposal.description_digest, hash_of_foo)) + self.assertEqual(proposal.supply, self.supply) + self.assertEqual(proposal.total, 0) + self.assertEqual(proposal.block_deadline, self.proposal_block_height + 100) + self.assertEqual(proposal.target_vote_ppm, 500000) + self.assertTrue(same_hex(proposal.proposer, self.ivan)) + self.assertEqual(proposal.state, ProposalState.INIT) + + o = c.current_proposal_idx(self.voter_address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + idx = int(r, 16) + self.assertEqual(idx, 0) + + + def test_vote(self): + nonce_oracle = RPCNonceOracle(self.alice, 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[1], description, 100) + (tx_hash, o) = c.vote(self.voter_address, self.alice, 10) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, 100) + self.rpc.do(o) + + nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.vote(self.voter_address, self.alice, 10) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, 100) + self.rpc.do(o) + + + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.vote(self.voter_address, self.alice, 10) self.rpc.do(o) o = receipt(tx_hash) r = self.rpc.do(o) self.assertEqual(r['status'], 1) + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.vote(self.voter_address, self.alice, 90) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + # fail because all votes used + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.vote(self.voter_address, self.alice, 1) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + + + def test_vote_win(self): + half_supply = self.initial_supply / 2 + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, half_supply) + self.rpc.do(o) + + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.bob, half_supply) + self.rpc.do(o) + + nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, half_supply) + self.rpc.do(o) + + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.vote(self.voter_address, self.alice, half_supply) + self.rpc.do(o) + + 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) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 0) + o = block_latest() - block_height = self.rpc.do(o) + now_block_height = self.rpc.do(o) + need_blocks = self.proposal_block_height + 100 - now_block_height + 1 + self.backend.mine_blocks(need_blocks) o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) r = self.rpc.do(o) proposal = c.parse_proposal(r) - logg.debug('proposal {}'.format(proposal)) - self.assertTrue(same_hex(proposal.description_digest, description)) - self.assertEqual(proposal.supply, self.supply) - self.assertEqual(proposal.total, 0) - self.assertEqual(proposal.block_deadline, block_height + 100) - self.assertEqual(proposal.target_vote_ppm, 500000) - self.assertTrue(same_hex(proposal.proposer, self.alice)) self.assertEqual(proposal.state, ProposalState.INIT) + 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) + 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.SCANNED, ProposalState.SCANNED) + + (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.INSUFFICIENT, 0) + self.assertEqual(proposal.state & ProposalState.TIED, 0) + + + def test_vote_insufficient(self): + half_supply = self.initial_supply / 2 + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, half_supply) + self.rpc.do(o) + + nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.bob, half_supply) + self.rpc.do(o) + + nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, half_supply) + self.rpc.do(o) + + c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.vote(self.voter_address, self.alice, half_supply - 1) + self.rpc.do(o) + + o = block_latest() + now_block_height = self.rpc.do(o) + need_blocks = self.proposal_block_height + 100 - now_block_height + 1 + self.backend.mine_blocks(need_blocks) + + 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) + 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.SCANNED, ProposalState.SCANNED) + + (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.INSUFFICIENT, ProposalState.INSUFFICIENT) + self.assertEqual(proposal.state & ProposalState.TIED, 0) + if __name__ == '__main__': unittest.main() diff --git a/solidity/Vote_fail.sol b/solidity/Vote_fail.sol @@ -1,319 +0,0 @@ -pragma solidity ^0.8.0; - -// Author: Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 -// SPDX-License-Identifier: AGPL-3.0-or-later -// File-Version: 1 -// Description: Voting contract using ERC20 tokens as shares - -contract ERC20Vote { - address public token; - - struct Proposal { - bytes32 digest; - bytes32 state; - uint256 voterMax; - address proposer; - uint256 ackBlockDeadline; - uint256 voteBlockDeadline; - uint256 voteTargetPpm; - uint256 scanCursor; - address []voters; - bool valid; - bool active; - bool ackScanDone; - bool voteScanDone; - bool result; - } - Proposal emptyProposal; - - mapping ( address => uint256 ) voterState; - address[] voters; - mapping ( uint256 => mapping ( address => uint256 ) ) ack; - mapping ( uint256 => mapping ( address => uint256 ) ) vote; - mapping ( uint256 => uint256 ) tally; - mapping ( uint256 => uint256 ) budget; - - Proposal[] public proposals; - - uint256 public proposalCursor; - - event ProposalAdded(uint256 indexed _proposalIdx, uint256 indexed _ackBlockDeadline, uint256 indexed voteTargetPpm); - event VotesAdded(uint256 indexed _proposalIdx, address indexed _voter, uint256 indexed _total, uint256 _delta); - event VotesWithdrawn(uint256 indexed _proposalIdx, address indexed _voter, uint256 indexed _total, uint256 _delta); - event VoteResult(uint256 indexed _proposaldx, bool result); - event ProposalInvalid(uint256 _proposalIdx); - - constructor(address _token, address _secondVoter) { - token = _token; - voters.push(msg.sender); - voterState[msg.sender] = block.number; - voters.push(_secondVoter); - voterState[_secondVoter] = block.number; - } - - // Resolve voter address by index voter was added. - // Deactivates voter if balance is 0, activates voter if balance is 1. - function getVoter(uint256 _voterIdx) public returns (address) { - uint256 balance; - address voter; - - voter = voters[_voterIdx]; - balance = getBalance(voter); - if (balance == 0) { - voterState[voter] = 0; - } else if (voterState[voter] == 0) { - voterState[voter] = block.number; - } - return voter; - } - - // bounded sequential control of all proposals, to avoid gas lockout. - // protects the voter population from changing between a vote has been proposed and it has been processed - function scanProposal(uint256 _count) public returns (bool) { - uint256 i; - uint256 delta; - Proposal storage proposal; - - if (proposalCursor + _count > proposals.length) { - _count = proposals.length - proposalCursor; - } - - for (i = proposalCursor; i < proposals.length; i++) { - proposal = proposals[proposalCursor]; - if (!proposal.active) { - delta += 1; - } - } - proposalCursor += delta; - if (proposalCursor == proposals.length) { - return false; - } - return true; - } - - // bounded processing of acks for a proposal, to avoid gas lockout. - // when complete, relevant acks will be committed to the proposal and voting ratification can be possible. - function scanAck(uint256 _proposalIdx, uint256 _count) public returns (bool) { - Proposal storage proposal; - uint256 i; - - proposal = getActive(_proposalIdx); - - require(!proposal.ackScanDone); - - if (proposal.scanCursor + _count > voters.length) { - _count = voters.length - proposal.scanCursor; - } - - for (i = proposal.scanCursor; i < proposal.scanCursor + _count; i++) { - address voter; - if (i == proposal.voterMax) { - proposal.scanCursor = 0; - proposal.ackScanDone = true; - return false; - } - voter = getVoter(i); //voters[i]; - if (voterState[voter] > 0) { - proposal.voters.push(voter); - } - proposal.scanCursor = i; - } - return true; - } - - // bounded processing of votes, to avoid gas lockout. - // can only be called after voting deadline. - // adds all cast votes to the tally. - function scanVote(uint256 _proposalIdx, uint256 _count) public returns (bool) { - Proposal storage proposal; - uint256 i; - - proposal = getActive(_proposalIdx); - require(proposal.voteBlockDeadline <= block.timestamp); - require(!proposal.voteScanDone); - - if (proposal.scanCursor + _count > proposal.voters.length) { - _count = proposal.voters.length - proposal.scanCursor; - } - - for (i = proposal.scanCursor; i < proposal.scanCursor + _count; i++) { - address voter; - if (checkProposalBalance(_proposalIdx, voter) == 0) { - return false; - } - if (i == proposal.voters.length) { - proposal.scanCursor = 0; - proposal.voteScanDone = true; - return false; - } - voter = voters[i]; - tally[_proposalIdx] += vote[_proposalIdx][voter]; - proposal.scanCursor = i; - } - return true; - } - - // finalize proposal and result. - function ratify(uint256 _proposalIdx) public returns (bool) { - Proposal storage proposal; - uint256 tallyPpm; - uint256 budgetPpm; - - proposal = getActive(_proposalIdx); - - require(proposal.voteScanDone, "ERR_VOTE_SCAN_MISSING"); - - tallyPpm = tally[_proposalIdx] * 1000000; - budgetPpm = budget[_proposalIdx] * 1000000; - - if (tallyPpm / budgetPpm >= proposal.voteTargetPpm) { - proposal.result = true; - } - proposal.active = false; - emit VoteResult(_proposalIdx, proposal.result); - return proposal.result; - } - - // Common code for propose and proposeVoter. - function proposeCore(bytes32 _digest, uint256 _ackBlockDeadline, uint256 _voteBlockDeadline, uint256 _voteTargetPpm) private returns (uint256) { - require(_ackBlockDeadline > block.number); - require(_voteBlockDeadline > _ackBlockDeadline); - require(voters.length > 1); - - Proposal memory proposal; - uint256 idx; - - proposal.digest = _digest; - proposal.proposer = msg.sender; - proposal.voterMax = voters.length - 1; - proposal.ackBlockDeadline = _ackBlockDeadline; - proposal.voteBlockDeadline = _voteBlockDeadline; - proposal.valid = true; - proposal.active = true; - proposal.voteTargetPpm = _voteTargetPpm; - - idx = proposals.length; - proposals.push(proposal); - - return idx; - } - - // Propose a vote on the subject described by digest. - function propose(bytes32 _digest, uint256 _ackBlockDeadline, uint256 _voteBlockDeadline, uint256 _voteTargetPpm) public returns (uint256) { - uint256 r; - - r = proposeCore(_digest, _ackBlockDeadline, _voteBlockDeadline, _voteTargetPpm); - emit ProposalAdded(r, _ackBlockDeadline, _voteTargetPpm); - return r; - } - - // returns the active state. - function getActive(uint256 _proposalIdx) private returns (Proposal storage) { - Proposal storage proposal; - - proposal = proposals[_proposalIdx]; - if (!proposal.valid) { - return emptyProposal; - } - if (!proposal.active) { - return emptyProposal; - } - if (block.number >= proposal.voteBlockDeadline) { - proposal.active = false; - } - return proposal; - } - - // register ack for a proposal - function ackProposal(uint256 _proposalIdx) public returns (bool) { - Proposal storage proposal; - uint256 balance; - - proposal = getActive(_proposalIdx); - require(proposal.active, "ERR_PROPOSAL_INACTIVE"); - require(proposal.ackBlockDeadline < block.number, "ERR_ACK_EXPIRE"); - - if (ack[_proposalIdx][msg.sender] > 0) { - return false; - } - balance = getBalance(msg.sender); - ack[_proposalIdx][msg.sender] = balance; - budget[_proposalIdx] += balance; - return true; - } - - // spend votes on proposal - function spendVote(uint256 _proposalIdx, uint256 _amount) public returns (uint256) { - uint256 balance; - uint256 usedBalance; - Proposal storage proposal; - - proposal = getActive(_proposalIdx); - require(proposal.active, "ERR_PROPOSAL_INACTIVE"); - - balance = checkProposalBalance(_proposalIdx, msg.sender); - if (balance == 0) { - return 0; - } - - usedBalance = vote[_proposalIdx][msg.sender]; - require(balance - usedBalance >= _amount); - usedBalance += _amount; - vote[_proposalIdx][msg.sender] = usedBalance; - emit VotesAdded(_proposalIdx, msg.sender, usedBalance, _amount); - - return usedBalance; - } - - // withdraw spent votes on proposal - function withdrawVote(uint256 _proposalIdx, uint256 _amount) public returns (uint256) { - Proposal storage proposal; - uint256 balance; - uint256 usedBalance; - - proposal = getActive(_proposalIdx); - require(proposal.active, "ERR_PROPOSAL_INACTIVE"); - - balance = checkProposalBalance(_proposalIdx, msg.sender); - if (balance == 0) { - return 0; - } - - usedBalance = vote[_proposalIdx][msg.sender]; - require(usedBalance >= _amount); - usedBalance -= _amount; - vote[_proposalIdx][msg.sender] = usedBalance; - emit VotesWithdrawn(_proposalIdx, msg.sender, usedBalance, _amount); - - return usedBalance; - } - - // retrieve token balance from backing erc20 token. - function getBalance(address _voter) private returns (uint256) { - bytes memory v; - bool ok; - - (ok, v) = token.call(abi.encodeWithSignature('balanceOf', _voter)); - require(ok); - return abi.decode(v, (uint256)); - } - - // invalidate proposal if terms of the vote has changed: - // * current voter balance does not match voter balance at time of acknowledgement - function checkProposalBalance(uint256 _proposalIdx, address _voter) private returns (uint256) { - uint256 balance; - uint256 origBalance; - - balance = getBalance(_voter); - origBalance = ack[_proposalIdx][_voter]; - if (balance != origBalance) { - Proposal storage proposal; - proposal = proposals[_proposalIdx]; - proposal.valid = false; - proposal.active = false; - emit ProposalInvalid(_proposalIdx); - return 0; - } - return balance; - } -} diff --git a/solidity/Voter.sol b/solidity/Voter.sol @@ -90,23 +90,26 @@ contract ERC20Vote { } // Cast votes on an option by locking ERC20 token in contract. - // Votes may be divided on several options. + // Votes may be divided on several options as long as balance is sufficient. // If false is returned, proposal has been invalidated. - function vote(uint256 _optionIndex, uint256 _value) public returns (bool) { + function voteOption(uint256 _optionIndex, uint256 _value) public returns (bool) { Proposal storage proposal; bool r; bytes memory v; mustAccount(msg.sender); proposal = proposals[currentProposal]; + require(proposal.state & STATE_INIT > 0, "ERR_PROPOSAL_INACTIVE"); if (checkSupply(proposal) == 0) { return false; } - require(proposal.blockDeadline < block.number, "ERR_DEADLINE"); + require(proposal.blockDeadline > block.number, "ERR_DEADLINE"); if (proposalIdxLock[msg.sender] > 0) { require(proposalIdxLock[msg.sender] == currentProposal, "ERR_RECOVER_FIRST"); } - require(_optionIndex < proposal.options.length, "ERR_OPTION_INVALID"); + if (proposal.options.length > 0) { + require(_optionIndex < proposal.options.length, "ERR_OPTION_INVALID"); + } (r, v) = token.call(abi.encodeWithSignature('transferFrom(address,address,uint256)', msg.sender, this, _value)); require(r, "ERR_TOKEN"); @@ -116,10 +119,19 @@ contract ERC20Vote { proposalIdxLock[msg.sender] = currentProposal; balanceOf[msg.sender] += _value; proposal.total += _value; - proposal.optionVotes[_optionIndex] += _value; + if (proposal.options.length > 0) { + proposal.optionVotes[_optionIndex] += _value; + } return true; } + // Cast vote for a proposal without options + // Can be called multiple times as long as balance is sufficient. + // If false is returned, proposal has been invalidated. + function vote(uint256 _value) public returns (bool) { + return voteOption(0, _value); + } + // Optionally scan the results for a proposal to make result visible. // Returns false as long as there are more options to scan. function scan(uint256 _proposalIndex, uint8 _count) public returns (bool) { @@ -137,6 +149,11 @@ contract ERC20Vote { return false; } + if (proposal.options.length == 0) { + proposal.state |= STATE_SCANNED; + return true; + } + c = proposal.scanCursor; if (c + _count > proposal.options.length) { _count = uint8(proposal.options.length) - c; @@ -168,11 +185,10 @@ contract ERC20Vote { function finalize() public returns (bool) { Proposal storage proposal; uint256 l_total_m; - uint256 l_supply_m; proposal = proposals[currentProposal]; require(proposal.state & STATE_FINAL == 0, "ERR_ALREADY_STATE_FINAL"); - require(proposal.state & STATE_SCANNED == 0, "ERR_SCAN_FIRST"); + require(proposal.state & STATE_SCANNED > 0, "ERR_SCAN_FIRST"); if (checkSupply(proposal) == 0) { return false; } @@ -180,9 +196,8 @@ contract ERC20Vote { currentProposal += 1; l_total_m = proposal.total * 1000000; - l_supply_m = proposal.supply * 1000000; - if (l_supply_m / l_total_m < proposal.targetVotePpm) { + if (l_total_m / proposal.supply < proposal.targetVotePpm) { proposal.state |= STATE_INSUFFICIENT; return false; @@ -203,7 +218,7 @@ contract ERC20Vote { require(l_supply > 0, "ERR_ZERO_SUPPLY"); if (proposal.supply == 0) { proposal.supply = l_supply; - } else { + } else if (l_supply != proposal.supply) { proposal.state |= STATE_SUPPLYCHANGE; proposal.state |= STATE_FINAL; currentProposal += 1;