From 5d9108a1384cb53f73d23906d7085d212425b77b Mon Sep 17 00:00:00 2001 From: Aaryamann Challani <43716372+rymnc@users.noreply.github.com> Date: Tue, 23 Jan 2024 23:20:33 +0530 Subject: [PATCH] feat: rln-v2 (#35) * feat: init rln-v2 changes * chore: remove poseidont3, dont calculate rate commitments * fix: deploy script * feat: add g16 verifier * chore: deploy to sepolia and polygon-zkevm-testnet * chore: snapshot * fix(rln): reuse getDepositAmount func --- .gas-snapshot | 32 +- deployments/11155111/latest.json | 45 +++ deployments/1442/latest.json | 23 +- script/Deploy.s.sol | 2 +- src/IVerifier.sol | 8 +- src/Rln.sol | 3 +- src/RlnBase.sol | 55 +++- src/RlnVerifier.sol | 487 ++++++++++++------------------- test/Rln.t.sol | 54 ++-- 9 files changed, 345 insertions(+), 364 deletions(-) create mode 100644 deployments/11155111/latest.json diff --git a/.gas-snapshot b/.gas-snapshot index a3cb4a1..420ecbf 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,15 +1,17 @@ -RlnTest:test__Constants() (gas: 7921) -RlnTest:test__InvalidRegistration__DuplicateCommitment(uint256) (runs: 1000, μ: 120248, ~: 120248) -RlnTest:test__InvalidRegistration__FullSet() (gas: 1242442) -RlnTest:test__InvalidRegistration__InsufficientDeposit(uint256) (runs: 1000, μ: 17189, ~: 17189) -RlnTest:test__InvalidRegistration__InvalidIdCommitment(uint256) (runs: 1000, μ: 16963, ~: 16968) -RlnTest:test__InvalidSlash__InvalidProof() (gas: 958986) -RlnTest:test__InvalidSlash__MemberNotRegistered(uint256) (runs: 1000, μ: 30287, ~: 30287) -RlnTest:test__InvalidSlash__NoStake(uint256,address) (runs: 1000, μ: 301136, ~: 301143) -RlnTest:test__InvalidSlash__ToRlnAddress() (gas: 128396) -RlnTest:test__InvalidSlash__ToZeroAddress() (gas: 128301) -RlnTest:test__InvalidWithdraw__InsufficientContractBalance() (gas: 126872) -RlnTest:test__InvalidWithdraw__InsufficientWithdrawalBalance() (gas: 10494) -RlnTest:test__ValidRegistration(uint256) (runs: 1000, μ: 112053, ~: 112053) -RlnTest:test__ValidSlash(uint256,address) (runs: 1000, μ: 184955, ~: 184966) -RlnTest:test__ValidWithdraw(address) (runs: 1000, μ: 183699, ~: 183687) \ No newline at end of file +RlnTest:test__Constants() (gas: 8619) +RlnTest:test__InvalidRegistration__DuplicateCommitment(uint256) (runs: 1000, μ: 144113, ~: 144113) +RlnTest:test__InvalidRegistration__FullSet() (gas: 1433224) +RlnTest:test__InvalidRegistration__InsufficientDeposit(uint256) (runs: 1000, μ: 17440, ~: 17440) +RlnTest:test__InvalidRegistration__InvalidIdCommitment(uint256) (runs: 1000, μ: 17053, ~: 17058) +RlnTest:test__InvalidRegistration__InvalidUserMessageLimit() (gas: 17055) +RlnTest:test__InvalidRegistration__MaxUserMessageLimit() (gas: 17203) +RlnTest:test__InvalidSlash__InvalidProof() (gas: 1081919) +RlnTest:test__InvalidSlash__MemberNotRegistered(uint256) (runs: 1000, μ: 32521, ~: 32521) +RlnTest:test__InvalidSlash__NoStake(uint256,address) (runs: 1000, μ: 319630, ~: 319682) +RlnTest:test__InvalidSlash__ToRlnAddress() (gas: 151034) +RlnTest:test__InvalidSlash__ToZeroAddress() (gas: 150939) +RlnTest:test__InvalidWithdraw__InsufficientContractBalance() (gas: 145224) +RlnTest:test__InvalidWithdraw__InsufficientWithdrawalBalance() (gas: 10538) +RlnTest:test__ValidRegistration(uint256) (runs: 1000, μ: 135760, ~: 135760) +RlnTest:test__ValidSlash(uint256,address) (runs: 1000, μ: 203402, ~: 203412) +RlnTest:test__ValidWithdraw(address) (runs: 1000, μ: 202120, ~: 202108) \ No newline at end of file diff --git a/deployments/11155111/latest.json b/deployments/11155111/latest.json new file mode 100644 index 0000000..35b03e1 --- /dev/null +++ b/deployments/11155111/latest.json @@ -0,0 +1,45 @@ +[ + { + "hash": "0x5a916693fe596872c5ca5eebf14ae7cc027aa8b245c0ba7c5a7ba0c6cc6bdde8", + "transactionType": "CREATE", + "contractName": "Verifier", + "contractAddress": "0xEba4B7e7825D5Ed7A6A28b19200cc5382dC2F90E", + "function": null, + "arguments": null, + "transaction": { + "type": "0x02", + "from": "0x3f47b2a1df96de2e198d646b598c37251ccc3b98", + "gas": "0x723d7", + "value": "0x0", + "data": "0x608060405234801561001057600080fd5b5061058c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f5c9d69e14610030575b600080fd5b61004361003e36600461052c565b610057565b604051901515815260200160405180910390f35b60006104ca565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47811061008f576000805260206000f35b50565b600060405183815284602082015285604082015260408160608360076107d05a03fa9150816100c5576000805260206000f35b825160408201526020830151606082015260408360808360066107d05a03fa915050806100f6576000805260206000f35b5050505050565b7f2b16fd00bd26d674287cfc25d02abf18b00fbc4964bb5b16b0f1077fec8f39be85527f22850edba988daec117b0bdae2ad24e5b5ac47186b0397c99905f7cfbcb3afff60208601526000608086018661019a87357f01e613151d854b94b0d8cd139333354f7394bf9582b47ee7fb125fd2f34a835f7f0374ef1ee7d1e0fbb80784c7b9a42a4c181413be097b9d64ca73417eec0c015384610092565b6101ea60208801357f1d63f0593a87129a1382a9c2be5e2c6d3ff6bc0ee6368ef2718dda96d0e054207f086bc14fda17a135507164dfcce27b710fcb5668dee2505acbeecb8fad6500f884610092565b50823581527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760208401357f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4703066020820152833560408201526020840135606082015260408401356080820152606084013560a08201527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e260c08201527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660e08201527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101008201527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101208201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101408201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8610160820152600087015161018082015260206000018701516101a08201527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220820152843561024082015260208501356102608201527f1989a57421455a443e8ab54b97c7cb0dc8d29a27dd2707383b5ce30e0937f1516102808201527f2458e5e27fc38dd430c6d5645a9845c35ecdaaaa777a29a9f79d04da627816d06102a08201527f25713f6db21b3ec0da75d5469790fad53d92bd7071d63c6fb6a138cad97585dc6102c08201527f225c87839a50bfa218107b5904aa7829ed709137673fc6bfcce156f52dd462476102e08201526020816103008360086107d05a03fa9051169695505050505050565b60405161038081016040526104e2600084013561005e565b6104ef602084013561005e565b6104fc604084013561005e565b610509818486888a6100fd565b90508060005260206000f35b806040810183101561052657600080fd5b92915050565b600080600080610140858703121561054357600080fd5b61054d8686610515565b935060c085018681111561056057600080fd5b6040860193506105708782610515565b925050610581866101008701610515565b90509295919450925056", + "nonce": "0x991", + "accessList": [] + }, + "additionalContracts": [], + "isFixedGasLimit": false + }, + { + "hash": "0x449b676fdf6d2d897198c18007017f0b0d10a06153017ecf42aa5dad987bf71e", + "transactionType": "CREATE", + "contractName": "Rln", + "contractAddress": "0xb40d380FCbfCcb600da20FE0fF1908578355510d", + "function": null, + "arguments": [ + "0", + "20", + "20", + "0xEba4B7e7825D5Ed7A6A28b19200cc5382dC2F90E" + ], + "transaction": { + "type": "0x02", + "from": "0x3f47b2a1df96de2e198d646b598c37251ccc3b98", + "gas": "0x141c41", + "value": "0x0", + "data": "0x6101406040526000805534801561001557600080fd5b5060405161129b38038061129b83398101604081905261003491610066565b60a09390935260805260c08190526001901b60e0526001600160a01b03166101005263ffffffff4316610120526100b5565b6000806000806080858703121561007c57600080fd5b845160208601516040870151606088015192965090945092506001600160a01b03811681146100aa57600080fd5b939692955090935050565b60805160a05160c05160e051610100516101205161116d61012e600039600061027d0152600081816101ed0152610d0101526000818161046e0152610bdf015260006103ca0152600081816104e901528181610548015281816108a201526108f80152600081816101760152610803015261116d6000f3fe60806040526004361061015f5760003560e01c80639056a9bf116100c0578063c5b208ff11610074578063d66d6c1011610059578063d66d6c1014610490578063e493ef8c146104a3578063f220b9ec146104d757600080fd5b8063c5b208ff1461042f578063d0383d681461045c57600080fd5b806398366e35116100a557806398366e35146103b8578063ae74552a146103ec578063bc4991281461040257600080fd5b80639056a9bf1461035e578063933ebfdd1461038b57600080fd5b80634add651e116101175780636bdcc8ab116100fc5780636bdcc8ab146102e15780637671ac05146103115780638be9b1191461033e57600080fd5b80634add651e1461026b5780635daf08ca146102b457600080fd5b80632b7ac3f3116101485780632b7ac3f3146101db578063378de45b146102345780633ccfd60b1461025457600080fd5b806309aeb04c1461016457806322d9730c146101ab575b600080fd5b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101b757600080fd5b506101cb6101c6366004610eb2565b61050b565b60405190151581526020016101a2565b3480156101e757600080fd5b5061020f7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101a2565b34801561024057600080fd5b5061019861024f366004610eb2565b610541565b34801561026057600080fd5b5061026961056d565b005b34801561027757600080fd5b5061029f7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101a2565b3480156102c057600080fd5b506101986102cf366004610eb2565b60026020526000908152604090205481565b3480156102ed57600080fd5b506101cb6102fc366004610eb2565b60056020526000908152604090205460ff1681565b34801561031d57600080fd5b5061019861032c366004610eb2565b60046020526000908152604090205481565b34801561034a57600080fd5b50610269610359366004610eed565b610630565b34801561036a57600080fd5b50610198610379366004610eb2565b60036020526000908152604090205481565b34801561039757600080fd5b506103ab6103a6366004610f35565b610689565b6040516101a29190610f57565b3480156103c457600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b3480156103f857600080fd5b5061019860005481565b34801561040e57600080fd5b5061019861041d366004610eb2565b60016020526000908152604090205481565b34801561043b57600080fd5b5061019861044a366004610f9b565b60066020526000908152604090205481565b34801561046857600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b61026961049e366004610f35565b6107bd565b3480156104af57600080fd5b506101987f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b3480156104e357600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6000811580159061053b57507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182105b92915050565b600061053b7f000000000000000000000000000000000000000000000000000000000000000083610fee565b33600090815260066020526040812054908190036105b7576040517f6f50367a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b478111156105f1576040517f786e0a9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152600660205260408082208290555183156108fc0291849190818181858888f1935050505015801561062c573d6000803e3d6000fd5b5050565b8261063a8161050b565b610678576040517f7f3e75af000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61068384848461093c565b50505050565b60608183106106ce576040517f9ffcd53d000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260440161066f565b600054821115610714576040517f9ffcd53d000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260440161066f565b60006107208484611005565b67ffffffffffffffff81111561073857610738611018565b604051908082528060200260200182016040528015610761578160200160208202803683370190505b509050835b838110156107b557600081815260046020526040902054826107888784611005565b8151811061079857610798611047565b6020908102919091010152806107ad81611076565b915050610766565b509392505050565b816107c78161050b565b610800576040517f7f3e75af0000000000000000000000000000000000000000000000000000000081526004810182905260240161066f565b817f000000000000000000000000000000000000000000000000000000000000000081111561085e576040517f13a5e2ee0000000000000000000000000000000000000000000000000000000081526004810182905260240161066f565b8060000361089b576040517f13a5e2ee0000000000000000000000000000000000000000000000000000000081526004810182905260240161066f565b60006108c77f000000000000000000000000000000000000000000000000000000000000000085610fee565b905080341461092a576040517f25c3f46e0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015234602482015260440161066f565b610935858534610b95565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216301480610974575073ffffffffffffffffffffffffffffffffffffffff8216155b156109c3576040517f4a149d0800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161066f565b6000838152600360209081526040808320546005909252822054909160ff90911615159003610a21576040517f5a971ebb0000000000000000000000000000000000000000000000000000000081526004810185905260240161066f565b6000848152600160205260408120549003610a6b576040517faabeeba50000000000000000000000000000000000000000000000000000000081526004810185905260240161066f565b610a76848484610cfd565b610aac576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600160209081526040808320805460028452828520805490869055808652600485528386208690558986526005855283862080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055918590556003845282852085905573ffffffffffffffffffffffffffffffffffffffff881685526006909352908320805492939192849290610b4c9084906110ae565b909155505060408051878152602081018390527f62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a943910160405180910390a1505050505050565b50565b60008381526005602052604090205460ff1615610bdd576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060005410610c38576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054848252600260209081526040808420839055918352600481528183208690558583526005815281832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915581528183208490556003815281832085905591548151868152928301859052908201527fff42916a89d1f5125f7f47168ee59c2b3fc9246ad1b229082ee85b69d001b5d79060600160405180910390a16001600080828254610cf391906110ae565b9091555050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f5c9d69e604051806040016040528085600060088110610d5957610d59611047565b6020020135815260200185600160088110610d7657610d76611047565b6020020135905260408051608081018252868201359181019182529081906060820188600360200201358152508152602001604051806040016040528088600460088110610dc657610dc6611047565b6020020135815260200188600560088110610de357610de3611047565b60200201359052905260408051808201909152808760066020020135815260200187600760088110610e1757610e17611047565b602002013581525060405180604001604052808a81526020018973ffffffffffffffffffffffffffffffffffffffff168152506040518563ffffffff1660e01b8152600401610e6994939291906110e4565b602060405180830381865afa158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaa919061114b565b949350505050565b600060208284031215610ec457600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b9257600080fd5b6000806000610140808587031215610f0457600080fd5b843593506020850135610f1681610ecb565b9250848101861015610f2757600080fd5b506040840190509250925092565b60008060408385031215610f4857600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015610f8f57835183529284019291840191600101610f73565b50909695505050505050565b600060208284031215610fad57600080fd5b8135610fb881610ecb565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761053b5761053b610fbf565b8181038181111561053b5761053b610fbf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036110a7576110a7610fbf565b5060010190565b8082018082111561053b5761053b610fbf565b8060005b60028110156106835781518452602093840193909101906001016110c5565b61014081016110f382876110c1565b60408083018660005b6002811015611123576111108383516110c1565b91830191602091909101906001016110fc565b5050505061113460c08301856110c1565b6111426101008301846110c1565b95945050505050565b60006020828403121561115d57600080fd5b81518015158114610fb857600080fd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000eba4b7e7825d5ed7a6a28b19200cc5382dc2f90e", + "nonce": "0x992", + "accessList": [] + }, + "additionalContracts": [], + "isFixedGasLimit": false + } +] diff --git a/deployments/1442/latest.json b/deployments/1442/latest.json index d0e0bf1..d1c18ed 100644 --- a/deployments/1442/latest.json +++ b/deployments/1442/latest.json @@ -1,40 +1,41 @@ [ { - "hash": "0xe6fc0883f98f439d6c29967e5333d64b2a73f80c66c09bccf507a5be93e7c5b2", + "hash": "0x16ef5d96da09eb0e10fedf00046fca2bf1e28cdc0eaf321a37d124d434f53db4", "transactionType": "CREATE", "contractName": "Verifier", - "contractAddress": "0x7bEf717F9Da36fF31a7D657cBC3464C905d9Bcf7", + "contractAddress": "0xC47276E298f809cBCD787fF28e413E22DF481d2d", "function": null, "arguments": null, "transaction": { "type": "0x00", "from": "0x3f47b2a1df96de2e198d646b598c37251ccc3b98", - "gas": "0x157863", + "gas": "0x723d7", "value": "0x0", - "data": "0x608060405234801561001057600080fd5b506112b0806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f5c9d69e14610030575b600080fd5b61004361003e366004611102565b610057565b604051901515815260200160405180910390f35b6000610061610ef9565b60408051808201825287518152602080890151818301529083528151608081018352875151818401908152885183015160608084019190915290825283518085018552898401805151825251840151818501528284015284830191909152825180840184528751815287830151818401528484015282516002808252918101845260009390928301908036833701905050905060005b600281101561014657848160028110610112576101126111a2565b6020020151828281518110610129576101296111a2565b60209081029190910101528061013e81611200565b9150506100f7565b506101518183610172565b6000036101635760019250505061016a565b6000925050505b949350505050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018161019e6103a8565b9050806080015151855160016101b49190611238565b14610220576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f76657269666965722d6261642d696e707574000000000000000000000000000060448201526064015b60405180910390fd5b604080518082019091526000808252602082018190525b865181101561032b5783878281518110610253576102536111a2565b6020026020010151106102c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f76657269666965722d6774652d736e61726b2d7363616c61722d6669656c64006044820152606401610217565b6103178261031285608001518460016102db9190611238565b815181106102eb576102eb6111a2565b60200260200101518a8581518110610305576103056111a2565b60200260200101516107bb565b610876565b91508061032381611200565b915050610237565b50610354818360800151600081518110610347576103476111a2565b6020026020010151610876565b905061038a6103668660000151610934565b8660200151846000015185602001518587604001518b6040015189606001516109d3565b61039a57600193505050506103a2565b600093505050505b92915050565b6103b0610f4a565b6040805180820182527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e281527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19266020808301919091529083528151608080820184527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c8285019081527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab606080850191909152908352845180860186527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a781527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8818601528385015285840192909252835180820185527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c28186019081527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed828501528152845180860186527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b81527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa818601528185015285850152835180820185527f1b778bdaf7d2d76a141a64bf6d5983bfcf2040592634f45ab662dd189c5856198186019081527f23584d1f9abbf32341679c4658b203b6fcf47ea6adc1d5548d2ebcf391bf7f8c828501528152845180860186527f128ed9443a2a711317e24319e0d4493caa1460605ab227b56333b91aa93c953f81527f0af9de4d2a3221e54094ef319d9499be2b04296747bfdf80116ca0ddf1dbb277818601528185015291850191909152825160038082529181019093529082015b604080518082019091526000808252602082015281526020019060019003908161062c57505060808201908152604080518082019091527f03a901fcac85b5b11450b3c49766477fc01e5aff3a4b4ab323758526be9dde6181527f3011f38b83fb9e775234354ba1e0ff16490977bfb855cac99ed789c1426a72946020820152905180516000906106bf576106bf6111a2565b602002602001018190525060405180604001604052807f24797f78c49f4d82fb02fbdf871928765135de74f2674c16912163f87ef60d5a81526020017f1700fa863be1dd74edb8e8a969a2795f8a0bd5dd94c98e11a937004de3f091a38152508160800151600181518110610736576107366111a2565b602002602001018190525060405180604001604052807f15273ed6a7550a123c301f66798c2724218b80e7965ea13b8b1d2056b0deeb7c81526020017f263599b0396b575e21ee3248f704393e647c33d6e9580033eb8894da73ef82d481525081608001516002815181106107ad576107ad6111a2565b602002602001018190525090565b60408051808201909152600080825260208201526107d7610f9b565b835181526020808501519082015260408101839052600060608360808460076107d05a03fa9050808061080657fe5b508061086e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f70616972696e672d6d756c2d6661696c656400000000000000000000000000006044820152606401610217565b505092915050565b6040805180820190915260008082526020820152610892610fb9565b8351815260208085015181830152835160408301528301516060808301919091526000908360c08460066107d05a03fa905080806108cc57fe5b508061086e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f70616972696e672d6164642d6661696c656400000000000000000000000000006044820152606401610217565b604080518082019091526000808252602082015281517f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd479015801561097b57506020830151155b1561099b5750506040805180820190915260008082526020820152919050565b6040518060400160405280846000015181526020018285602001516109c0919061124b565b6109ca9084611286565b90529392505050565b60408051600480825260a08201909252600091829190816020015b60408051808201909152600080825260208201528152602001906001900390816109ee57505060408051600480825260a0820190925291925060009190602082015b610a38610fd7565b815260200190600190039081610a305790505090508a82600081518110610a6157610a616111a2565b60200260200101819052508882600181518110610a8057610a806111a2565b60200260200101819052508682600281518110610a9f57610a9f6111a2565b60200260200101819052508482600381518110610abe57610abe6111a2565b60200260200101819052508981600081518110610add57610add6111a2565b60200260200101819052508781600181518110610afc57610afc6111a2565b60200260200101819052508581600281518110610b1b57610b1b6111a2565b60200260200101819052508381600381518110610b3a57610b3a6111a2565b6020026020010181905250610b4f8282610b5e565b9b9a5050505050505050505050565b60008151835114610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f70616972696e672d6c656e677468732d6661696c6564000000000000000000006044820152606401610217565b82516000610bda826006611299565b905060008167ffffffffffffffff811115610bf757610bf7611033565b604051908082528060200260200182016040528015610c20578160200160208202803683370190505b50905060005b83811015610e5b57868181518110610c4057610c406111a2565b60200260200101516000015182826006610c5a9190611299565b610c65906000611238565b81518110610c7557610c756111a2565b602002602001018181525050868181518110610c9357610c936111a2565b60200260200101516020015182826006610cad9190611299565b610cb8906001611238565b81518110610cc857610cc86111a2565b602002602001018181525050858181518110610ce657610ce66111a2565b6020908102919091010151515182610cff836006611299565b610d0a906002611238565b81518110610d1a57610d1a6111a2565b602002602001018181525050858181518110610d3857610d386111a2565b60209081029190910181015151015182610d53836006611299565b610d5e906003611238565b81518110610d6e57610d6e6111a2565b602002602001018181525050858181518110610d8c57610d8c6111a2565b602002602001015160200151600060028110610daa57610daa6111a2565b602002015182610dbb836006611299565b610dc6906004611238565b81518110610dd657610dd66111a2565b602002602001018181525050858181518110610df457610df46111a2565b602002602001015160200151600160028110610e1257610e126111a2565b602002015182610e23836006611299565b610e2e906005611238565b81518110610e3e57610e3e6111a2565b602090810291909101015280610e5381611200565b915050610c26565b50610e64610ff7565b6000602082602086026020860160086107d05a03fa90508080610e8357fe5b5080610eeb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f70616972696e672d6f70636f64652d6661696c656400000000000000000000006044820152606401610217565b505115159695505050505050565b6040805160a081019091526000606082018181526080830191909152815260208101610f23610fd7565b8152602001610f45604051806040016040528060008152602001600081525090565b905290565b6040805160e08101909152600060a0820181815260c0830191909152815260208101610f74610fd7565b8152602001610f81610fd7565b8152602001610f8e610fd7565b8152602001606081525090565b60405180606001604052806003906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b6040518060400160405280610fea611015565b8152602001610f45611015565b60405180602001604052806001906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156110ac577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b600082601f8301126110c357600080fd5b6110cb611062565b8060408401858111156110dd57600080fd5b845b818110156110f75780358452602093840193016110df565b509095945050505050565b600080600080610140858703121561111957600080fd5b61112386866110b2565b9350604086605f87011261113657600080fd5b61113e611062565b8060c088018981111561115057600080fd5b8389015b81811015611175576111668b826110b2565b84526020909301928401611154565b508196506111838a826110b2565b9550505050506111978661010087016110b2565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611231576112316111d1565b5060010190565b808201808211156103a2576103a26111d1565b600082611281577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b818103818111156103a2576103a26111d1565b80820281158282048414176103a2576103a26111d156", - "nonce": "0x30" + "data": "0x608060405234801561001057600080fd5b5061058c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f5c9d69e14610030575b600080fd5b61004361003e36600461052c565b610057565b604051901515815260200160405180910390f35b60006104ca565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47811061008f576000805260206000f35b50565b600060405183815284602082015285604082015260408160608360076107d05a03fa9150816100c5576000805260206000f35b825160408201526020830151606082015260408360808360066107d05a03fa915050806100f6576000805260206000f35b5050505050565b7f2b16fd00bd26d674287cfc25d02abf18b00fbc4964bb5b16b0f1077fec8f39be85527f22850edba988daec117b0bdae2ad24e5b5ac47186b0397c99905f7cfbcb3afff60208601526000608086018661019a87357f01e613151d854b94b0d8cd139333354f7394bf9582b47ee7fb125fd2f34a835f7f0374ef1ee7d1e0fbb80784c7b9a42a4c181413be097b9d64ca73417eec0c015384610092565b6101ea60208801357f1d63f0593a87129a1382a9c2be5e2c6d3ff6bc0ee6368ef2718dda96d0e054207f086bc14fda17a135507164dfcce27b710fcb5668dee2505acbeecb8fad6500f884610092565b50823581527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760208401357f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4703066020820152833560408201526020840135606082015260408401356080820152606084013560a08201527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e260c08201527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660e08201527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101008201527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101208201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101408201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8610160820152600087015161018082015260206000018701516101a08201527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220820152843561024082015260208501356102608201527f1989a57421455a443e8ab54b97c7cb0dc8d29a27dd2707383b5ce30e0937f1516102808201527f2458e5e27fc38dd430c6d5645a9845c35ecdaaaa777a29a9f79d04da627816d06102a08201527f25713f6db21b3ec0da75d5469790fad53d92bd7071d63c6fb6a138cad97585dc6102c08201527f225c87839a50bfa218107b5904aa7829ed709137673fc6bfcce156f52dd462476102e08201526020816103008360086107d05a03fa9051169695505050505050565b60405161038081016040526104e2600084013561005e565b6104ef602084013561005e565b6104fc604084013561005e565b610509818486888a6100fd565b90508060005260206000f35b806040810183101561052657600080fd5b92915050565b600080600080610140858703121561054357600080fd5b61054d8686610515565b935060c085018681111561056057600080fd5b6040860193506105708782610515565b925050610581866101008701610515565b90509295919450925056", + "nonce": "0x34" }, "additionalContracts": [], "isFixedGasLimit": false }, { - "hash": "0x6921c16bde53afd9abd40bcff7b4576c5ea816304b04662e21b28fb74b751dad", + "hash": "0xc18e3e62b4e5e4111457e03d963d1abb86f8155fae8e329252f193180bf366b0", "transactionType": "CREATE", "contractName": "Rln", - "contractAddress": "0xAD964626c0b394013a37d2a02A45e6ed68591A81", + "contractAddress": "0xa73c0A2191159a5ED3c5b1dAE533f59Cdc57265D", "function": null, "arguments": [ "0", "20", - "0x7bEf717F9Da36fF31a7D657cBC3464C905d9Bcf7" + "20", + "0xC47276E298f809cBCD787fF28e413E22DF481d2d" ], "transaction": { "type": "0x00", "from": "0x3f47b2a1df96de2e198d646b598c37251ccc3b98", - "gas": "0x11fe1b", + "gas": "0x141c41", "value": "0x0", - "data": "0x6101206040526000805534801561001557600080fd5b5060405161108238038061108283398101604081905261003491610062565b60809290925260a08190526001901b60c0526001600160a01b031660e05263ffffffff4316610100526100a8565b60008060006060848603121561007757600080fd5b83516020850151604086015191945092506001600160a01b038116811461009d57600080fd5b809150509250925092565b60805160a05160c05160e05161010051610f7a61010860003960006101ca01526000818161015a0152610b2501526000818161039c0152610a16015260006102f80152600081816104170152818161070401526107510152610f7a6000f3fe60806040526004361061010e5760003560e01c8063933ebfdd116100a5578063c5b208ff11610074578063e493ef8c11610059578063e493ef8c146103be578063f207564e146103f2578063f220b9ec1461040557600080fd5b8063c5b208ff1461035d578063d0383d681461038a57600080fd5b8063933ebfdd146102b957806398366e35146102e6578063ae74552a1461031a578063bc4991281461033057600080fd5b80635daf08ca116100e15780635daf08ca146102015780636bdcc8ab1461023c5780637671ac051461026c5780638be9b1191461029957600080fd5b806322d9730c146101135780632b7ac3f3146101485780633ccfd60b146101a15780634add651e146101b8575b600080fd5b34801561011f57600080fd5b5061013361012e366004610cd6565b610439565b60405190151581526020015b60405180910390f35b34801561015457600080fd5b5061017c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013f565b3480156101ad57600080fd5b506101b661046f565b005b3480156101c457600080fd5b506101ec7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161013f565b34801561020d57600080fd5b5061022e61021c366004610cd6565b60026020526000908152604090205481565b60405190815260200161013f565b34801561024857600080fd5b50610133610257366004610cd6565b60046020526000908152604090205460ff1681565b34801561027857600080fd5b5061022e610287366004610cd6565b60036020526000908152604090205481565b3480156102a557600080fd5b506101b66102b4366004610d11565b610532565b3480156102c557600080fd5b506102d96102d4366004610d59565b61058b565b60405161013f9190610d7b565b3480156102f257600080fd5b5061022e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561032657600080fd5b5061022e60005481565b34801561033c57600080fd5b5061022e61034b366004610cd6565b60016020526000908152604090205481565b34801561036957600080fd5b5061022e610378366004610dbf565b60056020526000908152604090205481565b34801561039657600080fd5b5061022e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ca57600080fd5b5061022e7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6101b6610400366004610cd6565b6106bf565b34801561041157600080fd5b5061022e7f000000000000000000000000000000000000000000000000000000000000000081565b6000811580159061046957507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182105b92915050565b33600090815260056020526040812054908190036104b9576040517f6f50367a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b478111156104f3576040517f786e0a9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152600560205260408082208290555183156108fc0291849190818181858888f1935050505015801561052e573d6000803e3d6000fd5b5050565b8261053c81610439565b61057a576040517f7f3e75af000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61058584848461078d565b50505050565b60608183106105d0576040517f9ffcd53d0000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610571565b600054821115610616576040517f9ffcd53d0000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610571565b60006106228484610e12565b67ffffffffffffffff81111561063a5761063a610e25565b604051908082528060200260200182016040528015610663578160200160208202803683370190505b509050835b838110156106b7576000818152600360205260409020548261068a8784610e12565b8151811061069a5761069a610e54565b6020908102919091010152806106af81610e83565b915050610668565b509392505050565b806106c981610439565b610702576040517f7f3e75af00000000000000000000000000000000000000000000000000000000815260048101829052602401610571565b7f00000000000000000000000000000000000000000000000000000000000000003414610783576040517f25c3f46e0000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152346024820152604401610571565b61052e82346109cc565b73ffffffffffffffffffffffffffffffffffffffff82163014806107c5575073ffffffffffffffffffffffffffffffffffffffff8216155b15610814576040517f4a149d0800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610571565b60008381526004602052604081205460ff1615159003610863576040517f5a971ebb00000000000000000000000000000000000000000000000000000000815260048101849052602401610571565b60008381526001602052604081205490036108ad576040517faabeeba500000000000000000000000000000000000000000000000000000000815260048101849052602401610571565b6108b8838383610b21565b6108ee576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600160209081526040808320805460028452828520805490869055808652600385528386208690558886526004855283862080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690559185905573ffffffffffffffffffffffffffffffffffffffff871685526005909352908320805492939192849290610984908490610ebb565b909155505060408051868152602081018390527f62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a943910160405180910390a15050505050565b50565b60008281526004602052604090205460ff1615610a14576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060005410610a6f576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054838252600260209081526040808420839055918352600381528183208590558483526004815281832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815281832084905591548151858152928301527f5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d2910160405180910390a16001600080828254610b189190610ebb565b90915550505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f5c9d69e604051806040016040528085600060088110610b7d57610b7d610e54565b6020020135815260200185600160088110610b9a57610b9a610e54565b6020020135905260408051608081018252868201359181019182529081906060820188600360200201358152508152602001604051806040016040528088600460088110610bea57610bea610e54565b6020020135815260200188600560088110610c0757610c07610e54565b60200201359052905260408051808201909152808760066020020135815260200187600760088110610c3b57610c3b610e54565b602002013581525060405180604001604052808a81526020018973ffffffffffffffffffffffffffffffffffffffff168152506040518563ffffffff1660e01b8152600401610c8d9493929190610ef1565b602060405180830381865afa158015610caa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cce9190610f58565b949350505050565b600060208284031215610ce857600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146109c957600080fd5b6000806000610140808587031215610d2857600080fd5b843593506020850135610d3a81610cef565b9250848101861015610d4b57600080fd5b506040840190509250925092565b60008060408385031215610d6c57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015610db357835183529284019291840191600101610d97565b50909695505050505050565b600060208284031215610dd157600080fd5b8135610ddc81610cef565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561046957610469610de3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610eb457610eb4610de3565b5060010190565b8082018082111561046957610469610de3565b8060005b6002811015610585578151845260209384019390910190600101610ed2565b6101408101610f008287610ece565b60408083018660005b6002811015610f3057610f1d838351610ece565b9183019160209190910190600101610f09565b50505050610f4160c0830185610ece565b610f4f610100830184610ece565b95945050505050565b600060208284031215610f6a57600080fd5b81518015158114610ddc57600080fd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000007bef717f9da36ff31a7d657cbc3464c905d9bcf7", - "nonce": "0x31" + "data": "0x6101406040526000805534801561001557600080fd5b5060405161129b38038061129b83398101604081905261003491610066565b60a09390935260805260c08190526001901b60e0526001600160a01b03166101005263ffffffff4316610120526100b5565b6000806000806080858703121561007c57600080fd5b845160208601516040870151606088015192965090945092506001600160a01b03811681146100aa57600080fd5b939692955090935050565b60805160a05160c05160e051610100516101205161116d61012e600039600061027d0152600081816101ed0152610d0101526000818161046e0152610bdf015260006103ca0152600081816104e901528181610548015281816108a201526108f80152600081816101760152610803015261116d6000f3fe60806040526004361061015f5760003560e01c80639056a9bf116100c0578063c5b208ff11610074578063d66d6c1011610059578063d66d6c1014610490578063e493ef8c146104a3578063f220b9ec146104d757600080fd5b8063c5b208ff1461042f578063d0383d681461045c57600080fd5b806398366e35116100a557806398366e35146103b8578063ae74552a146103ec578063bc4991281461040257600080fd5b80639056a9bf1461035e578063933ebfdd1461038b57600080fd5b80634add651e116101175780636bdcc8ab116100fc5780636bdcc8ab146102e15780637671ac05146103115780638be9b1191461033e57600080fd5b80634add651e1461026b5780635daf08ca146102b457600080fd5b80632b7ac3f3116101485780632b7ac3f3146101db578063378de45b146102345780633ccfd60b1461025457600080fd5b806309aeb04c1461016457806322d9730c146101ab575b600080fd5b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101b757600080fd5b506101cb6101c6366004610eb2565b61050b565b60405190151581526020016101a2565b3480156101e757600080fd5b5061020f7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101a2565b34801561024057600080fd5b5061019861024f366004610eb2565b610541565b34801561026057600080fd5b5061026961056d565b005b34801561027757600080fd5b5061029f7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101a2565b3480156102c057600080fd5b506101986102cf366004610eb2565b60026020526000908152604090205481565b3480156102ed57600080fd5b506101cb6102fc366004610eb2565b60056020526000908152604090205460ff1681565b34801561031d57600080fd5b5061019861032c366004610eb2565b60046020526000908152604090205481565b34801561034a57600080fd5b50610269610359366004610eed565b610630565b34801561036a57600080fd5b50610198610379366004610eb2565b60036020526000908152604090205481565b34801561039757600080fd5b506103ab6103a6366004610f35565b610689565b6040516101a29190610f57565b3480156103c457600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b3480156103f857600080fd5b5061019860005481565b34801561040e57600080fd5b5061019861041d366004610eb2565b60016020526000908152604090205481565b34801561043b57600080fd5b5061019861044a366004610f9b565b60066020526000908152604090205481565b34801561046857600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b61026961049e366004610f35565b6107bd565b3480156104af57600080fd5b506101987f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b3480156104e357600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6000811580159061053b57507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182105b92915050565b600061053b7f000000000000000000000000000000000000000000000000000000000000000083610fee565b33600090815260066020526040812054908190036105b7576040517f6f50367a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b478111156105f1576040517f786e0a9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152600660205260408082208290555183156108fc0291849190818181858888f1935050505015801561062c573d6000803e3d6000fd5b5050565b8261063a8161050b565b610678576040517f7f3e75af000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61068384848461093c565b50505050565b60608183106106ce576040517f9ffcd53d000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260440161066f565b600054821115610714576040517f9ffcd53d000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260440161066f565b60006107208484611005565b67ffffffffffffffff81111561073857610738611018565b604051908082528060200260200182016040528015610761578160200160208202803683370190505b509050835b838110156107b557600081815260046020526040902054826107888784611005565b8151811061079857610798611047565b6020908102919091010152806107ad81611076565b915050610766565b509392505050565b816107c78161050b565b610800576040517f7f3e75af0000000000000000000000000000000000000000000000000000000081526004810182905260240161066f565b817f000000000000000000000000000000000000000000000000000000000000000081111561085e576040517f13a5e2ee0000000000000000000000000000000000000000000000000000000081526004810182905260240161066f565b8060000361089b576040517f13a5e2ee0000000000000000000000000000000000000000000000000000000081526004810182905260240161066f565b60006108c77f000000000000000000000000000000000000000000000000000000000000000085610fee565b905080341461092a576040517f25c3f46e0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015234602482015260440161066f565b610935858534610b95565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216301480610974575073ffffffffffffffffffffffffffffffffffffffff8216155b156109c3576040517f4a149d0800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161066f565b6000838152600360209081526040808320546005909252822054909160ff90911615159003610a21576040517f5a971ebb0000000000000000000000000000000000000000000000000000000081526004810185905260240161066f565b6000848152600160205260408120549003610a6b576040517faabeeba50000000000000000000000000000000000000000000000000000000081526004810185905260240161066f565b610a76848484610cfd565b610aac576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600160209081526040808320805460028452828520805490869055808652600485528386208690558986526005855283862080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055918590556003845282852085905573ffffffffffffffffffffffffffffffffffffffff881685526006909352908320805492939192849290610b4c9084906110ae565b909155505060408051878152602081018390527f62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a943910160405180910390a1505050505050565b50565b60008381526005602052604090205460ff1615610bdd576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060005410610c38576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054848252600260209081526040808420839055918352600481528183208690558583526005815281832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915581528183208490556003815281832085905591548151868152928301859052908201527fff42916a89d1f5125f7f47168ee59c2b3fc9246ad1b229082ee85b69d001b5d79060600160405180910390a16001600080828254610cf391906110ae565b9091555050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f5c9d69e604051806040016040528085600060088110610d5957610d59611047565b6020020135815260200185600160088110610d7657610d76611047565b6020020135905260408051608081018252868201359181019182529081906060820188600360200201358152508152602001604051806040016040528088600460088110610dc657610dc6611047565b6020020135815260200188600560088110610de357610de3611047565b60200201359052905260408051808201909152808760066020020135815260200187600760088110610e1757610e17611047565b602002013581525060405180604001604052808a81526020018973ffffffffffffffffffffffffffffffffffffffff168152506040518563ffffffff1660e01b8152600401610e6994939291906110e4565b602060405180830381865afa158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaa919061114b565b949350505050565b600060208284031215610ec457600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b9257600080fd5b6000806000610140808587031215610f0457600080fd5b843593506020850135610f1681610ecb565b9250848101861015610f2757600080fd5b506040840190509250925092565b60008060408385031215610f4857600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015610f8f57835183529284019291840191600101610f73565b50909695505050505050565b600060208284031215610fad57600080fd5b8135610fb881610ecb565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761053b5761053b610fbf565b8181038181111561053b5761053b610fbf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036110a7576110a7610fbf565b5060010190565b8082018082111561053b5761053b610fbf565b8060005b60028110156106835781518452602093840193909101906001016110c5565b61014081016110f382876110c1565b60408083018660005b6002811015611123576111108383516110c1565b91830191602091909101906001016110fc565b5050505061113460c08301856110c1565b6111426101008301846110c1565b95945050505050565b60006020828403121561115d57600080fd5b81518015158114610fb857600080fd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000c47276e298f809cbcd787ff28e413e22df481d2d", + "nonce": "0x35" }, "additionalContracts": [], "isFixedGasLimit": false diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 47ebd76..13b343a 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -14,7 +14,7 @@ contract Deploy is BaseScript { // step 1: deploy the verifier Verifier verifier = new Verifier(); // step 2: deploy the rln contract - rln = new Rln(0, 20, address(verifier)); + rln = new Rln(0, 20, 20, address(verifier)); vm.stopBroadcast(); } } diff --git a/src/IVerifier.sol b/src/IVerifier.sol index fcf0767..20b0624 100644 --- a/src/IVerifier.sol +++ b/src/IVerifier.sol @@ -3,10 +3,10 @@ pragma solidity >=0.8.19; interface IVerifier { function verifyProof( - uint256[2] memory a, - uint256[2][2] memory b, - uint256[2] memory c, - uint256[2] memory input + uint256[2] calldata a, + uint256[2][2] calldata b, + uint256[2] calldata c, + uint256[2] calldata input ) external view diff --git a/src/Rln.sol b/src/Rln.sol index 5510453..31d7978 100644 --- a/src/Rln.sol +++ b/src/Rln.sol @@ -7,9 +7,10 @@ contract Rln is RlnBase { constructor( uint256 membershipDeposit, uint256 depth, + uint256 maxMessageLimit, address _verifier ) - RlnBase(membershipDeposit, depth, _verifier) + RlnBase(membershipDeposit, depth, maxMessageLimit, _verifier) { } function _validateRegistration(uint256 idCommitment) internal pure override { } diff --git a/src/RlnBase.sol b/src/RlnBase.sol index 7cc09b4..57c045b 100644 --- a/src/RlnBase.sol +++ b/src/RlnBase.sol @@ -21,6 +21,9 @@ error FailedValidation(); /// Invalid idCommitment error InvalidIdCommitment(uint256 idCommitment); +/// Invalid userMessageLimit +error InvalidUserMessageLimit(uint256 messageLimit); + /// Invalid receiver address, when the receiver is the contract itself or 0x0 error InvalidReceiverAddress(address to); @@ -47,6 +50,9 @@ abstract contract RlnBase { uint256 public constant Q = 21_888_242_871_839_275_222_246_405_745_257_275_088_548_364_400_416_034_343_698_204_186_575_808_495_617; + /// @notice The max message limit per epoch + uint256 public immutable MAX_MESSAGE_LIMIT; + /// @notice The deposit amount required to register as a member uint256 public immutable MEMBERSHIP_DEPOSIT; @@ -67,6 +73,10 @@ abstract contract RlnBase { /// maps from idCommitment to their index in the set mapping(uint256 => uint256) public members; + /// @notice the user message limit of each member + /// maps from idCommitment to their user message limit + mapping(uint256 => uint256) public userMessageLimits; + /// @notice the index to commitment mapping mapping(uint256 => uint256) public indexToCommitment; @@ -84,8 +94,9 @@ abstract contract RlnBase { /// Emitted when a new member is added to the set /// @param idCommitment The idCommitment of the member + /// @param userMessageLimit the user message limit of the member /// @param index The index of the member in the set - event MemberRegistered(uint256 idCommitment, uint256 index); + event MemberRegistered(uint256 idCommitment, uint256 userMessageLimit, uint256 index); /// Emitted when a member is removed from the set /// @param idCommitment The idCommitment of the member @@ -97,28 +108,54 @@ abstract contract RlnBase { _; } - constructor(uint256 membershipDeposit, uint256 depth, address _verifier) { + modifier onlyValidUserMessageLimit(uint256 messageLimit) { + if (messageLimit > MAX_MESSAGE_LIMIT) revert InvalidUserMessageLimit(messageLimit); + if (messageLimit == 0) revert InvalidUserMessageLimit(messageLimit); + _; + } + + constructor(uint256 membershipDeposit, uint256 depth, uint256 maxMessageLimit, address _verifier) { MEMBERSHIP_DEPOSIT = membershipDeposit; + MAX_MESSAGE_LIMIT = maxMessageLimit; DEPTH = depth; SET_SIZE = 1 << depth; verifier = IVerifier(_verifier); deployedBlockNumber = uint32(block.number); } + /// Returns the deposit amount required to register as a member + /// @param userMessageLimit The message limit of the member + /// TODO: update this function as per tokenomics design + function getDepositAmount(uint256 userMessageLimit) public view returns (uint256) { + return userMessageLimit * MEMBERSHIP_DEPOSIT; + } + /// Allows a user to register as a member /// @param idCommitment The idCommitment of the member - function register(uint256 idCommitment) external payable virtual onlyValidIdCommitment(idCommitment) { - if (msg.value != MEMBERSHIP_DEPOSIT) { + /// @param userMessageLimit The message limit of the member + function register( + uint256 idCommitment, + uint256 userMessageLimit + ) + external + payable + virtual + onlyValidIdCommitment(idCommitment) + onlyValidUserMessageLimit(userMessageLimit) + { + uint256 requiredDeposit = getDepositAmount(userMessageLimit); + if (msg.value != requiredDeposit) { revert InsufficientDeposit(MEMBERSHIP_DEPOSIT, msg.value); } _validateRegistration(idCommitment); - _register(idCommitment, msg.value); + _register(idCommitment, userMessageLimit, msg.value); } /// Registers a member /// @param idCommitment The idCommitment of the member + /// @param userMessageLimit The message limit of the member /// @param stake The amount of eth staked by the member - function _register(uint256 idCommitment, uint256 stake) internal virtual { + function _register(uint256 idCommitment, uint256 userMessageLimit, uint256 stake) internal virtual { if (memberExists[idCommitment]) revert DuplicateIdCommitment(); if (idCommitmentIndex >= SET_SIZE) revert FullTree(); @@ -126,8 +163,9 @@ abstract contract RlnBase { indexToCommitment[idCommitmentIndex] = idCommitment; memberExists[idCommitment] = true; stakedAmounts[idCommitment] = stake; + userMessageLimits[idCommitment] = userMessageLimit; - emit MemberRegistered(idCommitment, idCommitmentIndex); + emit MemberRegistered(idCommitment, userMessageLimit, idCommitmentIndex); idCommitmentIndex += 1; } @@ -158,6 +196,7 @@ abstract contract RlnBase { revert InvalidReceiverAddress(receiver); } + uint256 userMessageLimit = userMessageLimits[idCommitment]; if (memberExists[idCommitment] == false) revert MemberNotRegistered(idCommitment); // check if member is registered if (stakedAmounts[idCommitment] == 0) { @@ -176,7 +215,7 @@ abstract contract RlnBase { indexToCommitment[index] = 0; memberExists[idCommitment] = false; stakedAmounts[idCommitment] = 0; - // TODO: remove from IMT + userMessageLimits[idCommitment] = 0; // refund deposit withdrawalBalance[receiver] += amountToTransfer; diff --git a/src/RlnVerifier.sol b/src/RlnVerifier.sol index 81a58fd..842dc0f 100644 --- a/src/RlnVerifier.sol +++ b/src/RlnVerifier.sol @@ -1,330 +1,203 @@ -// File: https://github.com/Rate-Limiting-Nullifier/rln-contract-v1/blob/main/src/RLNVerifier.sol -// Copyright 2017 Christian Reitwiessner -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to the following conditions: -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -// Software. -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// 2019 OKIMS -// ported to solidity 0.6 -// fixed linter warnings -// added requiere error messages -// -// +// File: https://github.com/Rate-Limiting-Nullifier/rln-contract/blob/main/src/Verifier.sol // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.19; +/* + Copyright 2021 0KIMS association. -library Pairing { - struct G1Point { - uint256 X; - uint256 Y; - } - // Encoding of field elements is: X[0] * z + X[1] + This file is generated with [snarkJS](https://github.com/iden3/snarkjs). - struct G2Point { - uint256[2] X; - uint256[2] Y; - } - /// @return the generator of G1 + snarkJS is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - function P1() internal pure returns (G1Point memory) { - return G1Point(1, 2); - } - /// @return the generator of G2 + snarkJS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. - function P2() internal pure returns (G2Point memory) { - // Original code point - return G2Point( - [ - 11_559_732_032_986_387_107_991_004_021_392_285_783_925_812_861_821_192_530_917_403_151_452_391_805_634, - 10_857_046_999_023_057_135_944_570_762_232_829_481_370_756_359_578_518_086_990_519_993_285_655_852_781 - ], - [ - 4_082_367_875_863_433_681_332_203_403_145_435_568_316_851_327_593_401_208_105_741_076_214_120_093_531, - 8_495_653_923_123_431_417_604_973_247_489_272_438_418_190_587_263_600_148_770_280_649_306_958_101_930 - ] - ); + You should have received a copy of the GNU General Public License + along with snarkJS. If not, see . +*/ - /* - // Changed by Jordi point - return G2Point( - [10857046999023057135944570762232829481370756359578518086990519993285655852781, - 11559732032986387107991004021392285783925812861821192530917403151452391805634], - [8495653923123431417604973247489272438418190587263600148770280649306958101930, - 4082367875863433681332203403145435568316851327593401208105741076214120093531] - );*/ - } - /// @return r the negation of p, i.e. p.addition(p.negate()) should be zero. - - function negate(G1Point memory p) internal pure returns (G1Point memory r) { - // The prime q in the base field F_q for G1 - uint256 q = - 21_888_242_871_839_275_222_246_405_745_257_275_088_696_311_157_297_823_662_689_037_894_645_226_208_583; - if (p.X == 0 && p.Y == 0) { - return G1Point(0, 0); - } - return G1Point(p.X, q - (p.Y % q)); - } - /// @return r the sum of two points of G1 - - function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) { - uint256[4] memory input; - input[0] = p1.X; - input[1] = p1.Y; - input[2] = p2.X; - input[3] = p2.Y; - bool success; - // solium-disable-next-line security/no-inline-assembly - assembly { - success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60) - // Use "invalid" to make gas estimation work - switch success - case 0 { invalid() } - } - require(success, "pairing-add-failed"); - } - /// @return r the product of a point on G1 and a scalar, i.e. - /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p. - - function scalar_mul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) { - uint256[3] memory input; - input[0] = p.X; - input[1] = p.Y; - input[2] = s; - bool success; - // solium-disable-next-line security/no-inline-assembly - assembly { - success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60) - // Use "invalid" to make gas estimation work - switch success - case 0 { invalid() } - } - require(success, "pairing-mul-failed"); - } - /// @return the result of computing the pairing check - /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1 - /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should - /// return true. - - function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) { - require(p1.length == p2.length, "pairing-lengths-failed"); - uint256 elements = p1.length; - uint256 inputSize = elements * 6; - uint256[] memory input = new uint256[](inputSize); - for (uint256 i = 0; i < elements; i++) { - input[i * 6 + 0] = p1[i].X; - input[i * 6 + 1] = p1[i].Y; - input[i * 6 + 2] = p2[i].X[0]; - input[i * 6 + 3] = p2[i].X[1]; - input[i * 6 + 4] = p2[i].Y[0]; - input[i * 6 + 5] = p2[i].Y[1]; - } - uint256[1] memory out; - bool success; - // solium-disable-next-line security/no-inline-assembly - assembly { - success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) - // Use "invalid" to make gas estimation work - switch success - case 0 { invalid() } - } - require(success, "pairing-opcode-failed"); - return out[0] != 0; - } - /// Convenience method for a pairing check for two pairs. - - function pairingProd2( - G1Point memory a1, - G2Point memory a2, - G1Point memory b1, - G2Point memory b2 - ) - internal - view - returns (bool) - { - G1Point[] memory p1 = new G1Point[](2); - G2Point[] memory p2 = new G2Point[](2); - p1[0] = a1; - p1[1] = b1; - p2[0] = a2; - p2[1] = b2; - return pairing(p1, p2); - } - /// Convenience method for a pairing check for three pairs. - - function pairingProd3( - G1Point memory a1, - G2Point memory a2, - G1Point memory b1, - G2Point memory b2, - G1Point memory c1, - G2Point memory c2 - ) - internal - view - returns (bool) - { - G1Point[] memory p1 = new G1Point[](3); - G2Point[] memory p2 = new G2Point[](3); - p1[0] = a1; - p1[1] = b1; - p1[2] = c1; - p2[0] = a2; - p2[1] = b2; - p2[2] = c2; - return pairing(p1, p2); - } - /// Convenience method for a pairing check for four pairs. - - function pairingProd4( - G1Point memory a1, - G2Point memory a2, - G1Point memory b1, - G2Point memory b2, - G1Point memory c1, - G2Point memory c2, - G1Point memory d1, - G2Point memory d2 - ) - internal - view - returns (bool) - { - G1Point[] memory p1 = new G1Point[](4); - G2Point[] memory p2 = new G2Point[](4); - p1[0] = a1; - p1[1] = b1; - p1[2] = c1; - p1[3] = d1; - p2[0] = a2; - p2[1] = b2; - p2[2] = c2; - p2[3] = d2; - return pairing(p1, p2); - } -} +pragma solidity >=0.7.0 <0.9.0; contract Verifier { - using Pairing for *; + // Scalar field size + uint256 constant r = + 21_888_242_871_839_275_222_246_405_745_257_275_088_548_364_400_416_034_343_698_204_186_575_808_495_617; + // Base field size + uint256 constant q = + 21_888_242_871_839_275_222_246_405_745_257_275_088_696_311_157_297_823_662_689_037_894_645_226_208_583; - struct VerifyingKey { - Pairing.G1Point alfa1; - Pairing.G2Point beta2; - Pairing.G2Point gamma2; - Pairing.G2Point delta2; - Pairing.G1Point[] IC; - } + // Verification Key data + uint256 constant alphax = + 20_491_192_805_390_485_299_153_009_773_594_534_940_189_261_866_228_447_918_068_658_471_970_481_763_042; + uint256 constant alphay = + 9_383_485_363_053_290_200_918_347_156_157_836_566_562_967_994_039_712_273_449_902_621_266_178_545_958; + uint256 constant betax1 = + 4_252_822_878_758_300_859_123_897_981_450_591_353_533_073_413_197_771_768_651_442_665_752_259_397_132; + uint256 constant betax2 = + 6_375_614_351_688_725_206_403_948_262_868_962_793_625_744_043_794_305_715_222_011_528_459_656_738_731; + uint256 constant betay1 = + 21_847_035_105_528_745_403_288_232_691_147_584_728_191_162_732_299_865_338_377_159_692_350_059_136_679; + uint256 constant betay2 = + 10_505_242_626_370_262_277_552_901_082_094_356_697_409_835_680_220_590_971_873_171_140_371_331_206_856; + uint256 constant gammax1 = + 11_559_732_032_986_387_107_991_004_021_392_285_783_925_812_861_821_192_530_917_403_151_452_391_805_634; + uint256 constant gammax2 = + 10_857_046_999_023_057_135_944_570_762_232_829_481_370_756_359_578_518_086_990_519_993_285_655_852_781; + uint256 constant gammay1 = + 4_082_367_875_863_433_681_332_203_403_145_435_568_316_851_327_593_401_208_105_741_076_214_120_093_531; + uint256 constant gammay2 = + 8_495_653_923_123_431_417_604_973_247_489_272_438_418_190_587_263_600_148_770_280_649_306_958_101_930; + uint256 constant deltax1 = + 11_551_021_181_461_167_826_461_759_140_322_976_337_427_023_987_127_500_996_455_457_136_635_486_400_849; + uint256 constant deltax2 = + 16_440_331_697_014_556_916_876_897_072_677_669_680_121_386_347_171_004_539_353_252_116_876_383_229_648; + uint256 constant deltay1 = + 16_935_666_883_311_644_237_478_257_793_713_075_046_951_222_500_094_443_222_621_864_730_929_684_383_196; + uint256 constant deltay2 = + 15_542_122_065_551_809_636_611_024_015_159_689_732_218_122_471_819_623_718_488_423_844_152_861_811_271; - struct Proof { - Pairing.G1Point A; - Pairing.G2Point B; - Pairing.G1Point C; - } + uint256 constant IC0x = + 19_490_069_286_251_317_200_471_893_224_761_952_280_235_157_078_692_599_655_063_040_494_106_083_015_102; + uint256 constant IC0y = + 15_613_730_057_977_833_735_664_106_983_317_680_013_118_142_165_231_654_768_046_521_650_638_333_652_991; - function verifyingKey() internal pure returns (VerifyingKey memory vk) { - vk.alfa1 = Pairing.G1Point( - 20_491_192_805_390_485_299_153_009_773_594_534_940_189_261_866_228_447_918_068_658_471_970_481_763_042, - 9_383_485_363_053_290_200_918_347_156_157_836_566_562_967_994_039_712_273_449_902_621_266_178_545_958 - ); + uint256 constant IC1x = + 1_563_543_155_852_853_229_359_605_494_188_815_884_199_915_022_658_219_002_707_722_789_976_065_966_419; + uint256 constant IC1y = + 858_819_375_930_654_753_672_617_171_465_307_097_688_802_650_498_051_619_587_167_586_479_724_200_799; - vk.beta2 = Pairing.G2Point( - [ - 4_252_822_878_758_300_859_123_897_981_450_591_353_533_073_413_197_771_768_651_442_665_752_259_397_132, - 6_375_614_351_688_725_206_403_948_262_868_962_793_625_744_043_794_305_715_222_011_528_459_656_738_731 - ], - [ - 21_847_035_105_528_745_403_288_232_691_147_584_728_191_162_732_299_865_338_377_159_692_350_059_136_679, - 10_505_242_626_370_262_277_552_901_082_094_356_697_409_835_680_220_590_971_873_171_140_371_331_206_856 - ] - ); - vk.gamma2 = Pairing.G2Point( - [ - 11_559_732_032_986_387_107_991_004_021_392_285_783_925_812_861_821_192_530_917_403_151_452_391_805_634, - 10_857_046_999_023_057_135_944_570_762_232_829_481_370_756_359_578_518_086_990_519_993_285_655_852_781 - ], - [ - 4_082_367_875_863_433_681_332_203_403_145_435_568_316_851_327_593_401_208_105_741_076_214_120_093_531, - 8_495_653_923_123_431_417_604_973_247_489_272_438_418_190_587_263_600_148_770_280_649_306_958_101_930 - ] - ); - vk.delta2 = Pairing.G2Point( - [ - 12_423_666_958_566_268_737_444_308_034_237_892_912_702_648_013_927_558_883_280_319_245_968_679_130_649, - 15_986_964_528_637_281_931_410_749_976_607_406_939_789_163_617_014_270_799_373_312_764_775_965_360_012 - ], - [ - 8_394_023_076_056_524_902_583_796_202_128_496_802_110_914_536_948_580_183_128_578_071_394_816_660_799, - 4_964_607_673_011_101_982_600_772_762_445_991_192_038_811_950_832_626_693_345_350_322_823_626_470_007 - ] - ); - vk.IC = new Pairing.G1Point[](3); + uint256 constant IC2x = + 3_808_889_614_445_935_800_597_561_392_085_733_302_718_838_702_771_107_544_944_545_050_886_958_022_904; + uint256 constant IC2y = + 13_293_649_293_049_947_010_793_838_294_353_767_499_934_999_769_633_605_908_974_566_715_226_392_122_400; - vk.IC[0] = Pairing.G1Point( - 1_655_549_413_518_972_190_198_478_012_616_802_994_254_462_093_161_203_201_613_599_472_264_958_303_841, - 21_742_734_017_792_296_281_216_385_119_397_138_748_114_275_727_065_024_271_646_515_586_404_591_497_876 - ); + // Memory data + uint16 constant pVk = 0; + uint16 constant pPairing = 128; - vk.IC[1] = Pairing.G1Point( - 16_497_930_821_522_159_474_595_176_304_955_625_435_616_718_625_609_462_506_360_632_944_366_974_274_906, - 10_404_924_572_941_018_678_793_755_094_259_635_830_045_501_866_471_999_610_240_845_041_996_101_882_275 - ); - - vk.IC[2] = Pairing.G1Point( - 9_567_910_551_099_174_794_221_497_568_036_631_681_620_409_346_997_815_381_833_929_247_558_241_020_796, - 17_282_591_858_786_007_768_931_802_126_325_866_705_896_012_606_427_630_592_145_070_155_065_868_649_172 - ); - } - - function verify(uint256[] memory input, Proof memory proof) internal view returns (uint256) { - uint256 snark_scalar_field = - 21_888_242_871_839_275_222_246_405_745_257_275_088_548_364_400_416_034_343_698_204_186_575_808_495_617; - VerifyingKey memory vk = verifyingKey(); - require(input.length + 1 == vk.IC.length, "verifier-bad-input"); - // Compute the linear combination vk_x - Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); - for (uint256 i = 0; i < input.length; i++) { - require(input[i] < snark_scalar_field, "verifier-gte-snark-scalar-field"); - vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i])); - } - vk_x = Pairing.addition(vk_x, vk.IC[0]); - if ( - !Pairing.pairingProd4( - Pairing.negate(proof.A), proof.B, vk.alfa1, vk.beta2, vk_x, vk.gamma2, proof.C, vk.delta2 - ) - ) return 1; - return 0; - } - /// @return r bool true if proof is valid + uint16 constant pLastMem = 896; function verifyProof( - uint256[2] memory a, - uint256[2][2] memory b, - uint256[2] memory c, - uint256[2] memory input + uint256[2] calldata _pA, + uint256[2][2] calldata _pB, + uint256[2] calldata _pC, + uint256[2] calldata _pubSignals ) public view - returns (bool r) + returns (bool) { - Proof memory proof; - proof.A = Pairing.G1Point(a[0], a[1]); - proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]); - proof.C = Pairing.G1Point(c[0], c[1]); - uint256[] memory inputValues = new uint256[](input.length); - for (uint256 i = 0; i < input.length; i++) { - inputValues[i] = input[i]; - } - if (verify(inputValues, proof) == 0) { - return true; - } else { - return false; + assembly { + function checkField(v) { + if iszero(lt(v, q)) { + mstore(0, 0) + return(0, 0x20) + } + } + + // G1 function to multiply a G1 value(x,y) to value in an address + function g1_mulAccC(pR, x, y, s) { + let success + let mIn := mload(0x40) + mstore(mIn, x) + mstore(add(mIn, 32), y) + mstore(add(mIn, 64), s) + + success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) + + if iszero(success) { + mstore(0, 0) + return(0, 0x20) + } + + mstore(add(mIn, 64), mload(pR)) + mstore(add(mIn, 96), mload(add(pR, 32))) + + success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) + + if iszero(success) { + mstore(0, 0) + return(0, 0x20) + } + } + + function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk { + let _pPairing := add(pMem, pPairing) + let _pVk := add(pMem, pVk) + + mstore(_pVk, IC0x) + mstore(add(_pVk, 32), IC0y) + + // Compute the linear combination vk_x + + g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0))) + + g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32))) + + // -A + mstore(_pPairing, calldataload(pA)) + mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q)) + + // B + mstore(add(_pPairing, 64), calldataload(pB)) + mstore(add(_pPairing, 96), calldataload(add(pB, 32))) + mstore(add(_pPairing, 128), calldataload(add(pB, 64))) + mstore(add(_pPairing, 160), calldataload(add(pB, 96))) + + // alpha1 + mstore(add(_pPairing, 192), alphax) + mstore(add(_pPairing, 224), alphay) + + // beta2 + mstore(add(_pPairing, 256), betax1) + mstore(add(_pPairing, 288), betax2) + mstore(add(_pPairing, 320), betay1) + mstore(add(_pPairing, 352), betay2) + + // vk_x + mstore(add(_pPairing, 384), mload(add(pMem, pVk))) + mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) + + // gamma2 + mstore(add(_pPairing, 448), gammax1) + mstore(add(_pPairing, 480), gammax2) + mstore(add(_pPairing, 512), gammay1) + mstore(add(_pPairing, 544), gammay2) + + // C + mstore(add(_pPairing, 576), calldataload(pC)) + mstore(add(_pPairing, 608), calldataload(add(pC, 32))) + + // delta2 + mstore(add(_pPairing, 640), deltax1) + mstore(add(_pPairing, 672), deltax2) + mstore(add(_pPairing, 704), deltay1) + mstore(add(_pPairing, 736), deltay2) + + let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) + + isOk := and(success, mload(_pPairing)) + } + + let pMem := mload(0x40) + mstore(0x40, add(pMem, pLastMem)) + + // Validate that all evaluations ∈ F + + checkField(calldataload(add(_pubSignals, 0))) + + checkField(calldataload(add(_pubSignals, 32))) + + checkField(calldataload(add(_pubSignals, 64))) + + // Validate all evaluations + let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) + + mstore(0, isValid) + return(0, 0x20) } } } diff --git a/test/Rln.t.sol b/test/Rln.t.sol index bf41e98..40204ca 100644 --- a/test/Rln.t.sol +++ b/test/Rln.t.sol @@ -21,10 +21,11 @@ contract RlnTest is Test { trueVerifier = new TrueVerifier(); falseVerifier = new FalseVerifier(); - rln = new Rln(MEMBERSHIP_DEPOSIT, DEPTH, address(trueVerifier)); + rln = new Rln(MEMBERSHIP_DEPOSIT, DEPTH, MAX_MESSAGE_LIMIT, address(trueVerifier)); } uint256 public constant MEMBERSHIP_DEPOSIT = 1_000_000_000_000_000; + uint256 public constant MAX_MESSAGE_LIMIT = 20; uint256 public constant DEPTH = 20; uint256 public constant SET_SIZE = 1_048_576; uint256[8] public zeroedProof = [0, 0, 0, 0, 0, 0, 0, 0]; @@ -34,49 +35,68 @@ contract RlnTest is Test { assertEq(rln.MEMBERSHIP_DEPOSIT(), MEMBERSHIP_DEPOSIT); assertEq(rln.DEPTH(), DEPTH); assertEq(rln.SET_SIZE(), SET_SIZE); + assertEq(rln.MAX_MESSAGE_LIMIT(), MAX_MESSAGE_LIMIT); assertEq(rln.deployedBlockNumber(), 1); } function test__ValidRegistration(uint256 idCommitment) public { vm.assume(rln.isValidCommitment(idCommitment)); - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); assertEq(rln.memberExists(idCommitment), true); assertEq(rln.members(idCommitment), 0); + assertEq(rln.userMessageLimits(idCommitment), 1); } function test__InvalidRegistration__DuplicateCommitment(uint256 idCommitment) public { vm.assume(rln.isValidCommitment(idCommitment)); - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); assertEq(rln.memberExists(idCommitment), true); assertEq(rln.members(idCommitment), 0); + assertEq(rln.userMessageLimits(idCommitment), 1); vm.expectRevert(DuplicateIdCommitment.selector); - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); } function test__InvalidRegistration__InvalidIdCommitment(uint256 idCommitment) public { vm.assume(!rln.isValidCommitment(idCommitment)); vm.expectRevert(abi.encodeWithSelector(InvalidIdCommitment.selector, idCommitment)); - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); + } + + function test__InvalidRegistration__InvalidUserMessageLimit() public { + uint256 idCommitment = + 9_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820; + vm.assume(rln.isValidCommitment(idCommitment)); + vm.expectRevert(abi.encodeWithSelector(InvalidUserMessageLimit.selector, 0)); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 0); + } + + function test__InvalidRegistration__MaxUserMessageLimit() public { + uint256 idCommitment = + 9_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820; + vm.assume(rln.isValidCommitment(idCommitment)); + vm.expectRevert(abi.encodeWithSelector(InvalidUserMessageLimit.selector, MAX_MESSAGE_LIMIT + 1)); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, MAX_MESSAGE_LIMIT + 1); } function test__InvalidRegistration__InsufficientDeposit(uint256 idCommitment) public { vm.assume(rln.isValidCommitment(idCommitment)); uint256 badDepositAmount = MEMBERSHIP_DEPOSIT - 1; vm.expectRevert(abi.encodeWithSelector(InsufficientDeposit.selector, MEMBERSHIP_DEPOSIT, badDepositAmount)); - rln.register{ value: badDepositAmount }(idCommitment); + rln.register{ value: badDepositAmount }(idCommitment, 1); } function test__InvalidRegistration__FullSet() public { - Rln tempRln = new Rln(MEMBERSHIP_DEPOSIT, 2, address(rln.verifier())); + Rln tempRln = new Rln(MEMBERSHIP_DEPOSIT, 2, MAX_MESSAGE_LIMIT, address(rln.verifier())); uint256 setSize = tempRln.SET_SIZE(); for (uint256 i = 1; i <= setSize; i++) { - tempRln.register{ value: MEMBERSHIP_DEPOSIT }(i); + tempRln.register{ value: MEMBERSHIP_DEPOSIT }(i, 1); } assertEq(tempRln.idCommitmentIndex(), 4); vm.expectRevert(FullTree.selector); - tempRln.register{ value: MEMBERSHIP_DEPOSIT }(setSize + 1); + tempRln.register{ value: MEMBERSHIP_DEPOSIT }(setSize + 1, 1); } function test__ValidSlash(uint256 idCommitment, address payable to) public { @@ -87,7 +107,7 @@ contract RlnTest is Test { vm.assume(to != address(0)); vm.assume(rln.isValidCommitment(idCommitment)); - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); uint256 balanceBefore = to.balance; @@ -105,7 +125,7 @@ contract RlnTest is Test { uint256 idCommitment = 9_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820; - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); vm.expectRevert(abi.encodeWithSelector(InvalidReceiverAddress.selector, address(0))); rln.slash(idCommitment, payable(address(0)), zeroedProof); @@ -114,7 +134,7 @@ contract RlnTest is Test { function test__InvalidSlash__ToRlnAddress() public { uint256 idCommitment = 19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820; - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); vm.expectRevert(abi.encodeWithSelector(InvalidReceiverAddress.selector, address(rln))); rln.slash(idCommitment, payable(address(rln)), zeroedProof); @@ -134,7 +154,7 @@ contract RlnTest is Test { vm.assume(to != address(0)); vm.assume(rln.isValidCommitment(idCommitment)); - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); rln.slash(idCommitment, to, zeroedProof); @@ -152,9 +172,9 @@ contract RlnTest is Test { uint256 idCommitment = 19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820; - Rln tempRln = new Rln(MEMBERSHIP_DEPOSIT, 2, address(falseVerifier)); + Rln tempRln = new Rln(MEMBERSHIP_DEPOSIT, 2, MAX_MESSAGE_LIMIT, address(falseVerifier)); - tempRln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + tempRln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); vm.expectRevert(InvalidProof.selector); tempRln.slash(idCommitment, payable(address(this)), zeroedProof); @@ -168,7 +188,7 @@ contract RlnTest is Test { function test__InvalidWithdraw__InsufficientContractBalance() public { uint256 idCommitment = 19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820; - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); rln.slash(idCommitment, payable(address(this)), zeroedProof); assertEq(rln.stakedAmounts(idCommitment), 0); @@ -187,7 +207,7 @@ contract RlnTest is Test { uint256 idCommitment = 19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820; - rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment); + rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment, 1); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); rln.slash(idCommitment, to, zeroedProof); assertEq(rln.stakedAmounts(idCommitment), 0);