diff --git a/.circleci/config.yml b/.circleci/config.yml
index fc76c79..4391cfd 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -7,7 +7,7 @@ jobs:
build:
working_directory: ~/repo
docker:
- - image: circleci/node:10.18.1
+ - image: circleci/node:erbium
steps:
- checkout
- run:
@@ -49,7 +49,7 @@ jobs:
test:
working_directory: ~/repo
docker:
- - image: circleci/node:10.18.1
+ - image: circleci/node:erbium
steps:
- restore_cache:
keys:
diff --git a/packages/contract-artifacts/contracts/NoteStream.ts b/packages/contract-artifacts/contracts/NoteStream.ts
index bfe7aab..1b901da 100644
--- a/packages/contract-artifacts/contracts/NoteStream.ts
+++ b/packages/contract-artifacts/contracts/NoteStream.ts
@@ -242,9 +242,14 @@ export default {
type: 'address',
},
{
- internalType: 'bytes32',
- name: 'noteHash',
- type: 'bytes32',
+ internalType: 'bytes',
+ name: 'proof',
+ type: 'bytes',
+ },
+ {
+ internalType: 'bytes',
+ name: 'proofSignature',
+ type: 'bytes',
},
{
internalType: 'address',
@@ -435,9 +440,9 @@ export default {
},
],
bytecode:
- '0x60806040523480156200001157600080fd5b506040516200290b3803806200290b833981810160405260208110156200003757600080fd5b50516200005f620000506001600160e01b03620000fb16565b6001600160e01b03620000ff16565b6001805461ffff19166101001790556001600160a01b038116620000ca576040805162461bcd60e51b815260206004820181905260248201527f41434520636f6e747261637420697320746865207a65726f2061646472657373604482015290519081900360640190fd5b600180546001600160a01b03909216620100000262010000600160b01b031990921691909117815560025562000247565b3390565b6200011a8160006200015160201b620021401790919060201c565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6200016682826001600160e01b03620001de16565b15620001b9576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60006001600160a01b038216620002275760405162461bcd60e51b8152600401808060200182810382526022815260200180620028e96022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b61269280620002576000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80635c975abb116100715780635c975abb146103035780636ef8d66d1461030b57806382dc1ec4146103135780638456cb5914610339578063894e9a0d14610341578063911ab96c146103a8576100a9565b80631468a5d4146100ae5780631e99d569146101e25780633bc9e403146101fc5780633f4ba83a146102d557806346fbf68e146102dd575b600080fd5b6101e0600480360360808110156100c457600080fd5b81359190810190604081016020820135600160201b8111156100e557600080fd5b8201836020820111156100f757600080fd5b803590602001918460018302840111600160201b8311171561011857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561016a57600080fd5b82018360208201111561017c57600080fd5b803590602001918460018302840111600160201b8311171561019d57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506103e8915050565b005b6101ea6106f0565b60408051918252519081900360200190f35b6102c16004803603608081101561021257600080fd5b81359190810190604081016020820135600160201b81111561023357600080fd5b82018360208201111561024557600080fd5b803590602001918460018302840111600160201b8311171561026657600080fd5b919390929091602081019035600160201b81111561028357600080fd5b82018360208201111561029557600080fd5b803590602001918460018302840111600160201b831117156102b657600080fd5b9193509150356106f6565b604080519115158252519081900360200190f35b6101e0610a90565b6102c1600480360360208110156102f357600080fd5b50356001600160a01b0316610b79565b6102c1610b91565b6101e0610b9a565b6101e06004803603602081101561032957600080fd5b50356001600160a01b0316610bac565b6101e0610bfe565b61035e6004803603602081101561035757600080fd5b5035610cc4565b604080516001600160a01b039889168152968816602088015286810195909552929095166060850152608084015260a083019390935260c082019290925290519081900360e00190f35b6101ea600480360360a08110156103be57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135610d88565b600154610100900460ff16610444576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6001805461ff0019811690915560ff1615610499576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6000848152600360205260409020600601548490600160a01b900460ff16610500576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b60008581526003602052604090206004015485906001600160a01b0316331461055a5760405162461bcd60e51b81526004018080602001828103825260298152602001806126136029913960400191505060405180910390fd5b6000868152600360205260409020836105b2576040805162461bcd60e51b81526020600482015260156024820152741e995c9bc81d985b1d59481dda5d1a191c985dd85b605a1b604482015290519081900360640190fd5b600281015442906105c9908663ffffffff6110b216565b1061061b576040805162461bcd60e51b815260206004820181905260248201527f77697468647261772069732067726561746572207468616e20616c6c6f776564604482015290519081900360640190fd5b60015460609061063c906201000090046001600160a01b0316888785611113565b9150506000610662600160029054906101000a90046001600160a01b03168884866113e1565b808455600284015490915061067d908763ffffffff6110b216565b60028401556004830154600584015460408051848152602081018a905281516001600160a01b0394851694909316928d927fc40560fdf83328f954941bff2b9141084d3c22e88c89a758557961e1966a57a9928290030190a450506001805461ff00191661010017905550505050505050565b60025481565b600154600090610100900460ff16610755576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6001805461ff00191690556000878152600360205260409020600601548790600160a01b900460ff166107c7576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b60008881526003602052604090206005015488906001600160a01b031633148061080a57506000818152600360205260409020600401546001600160a01b031633145b6108455760405162461bcd60e51b815260040180806020018281038252603781526020018061256b6037913960400191505060405180910390fd5b60008981526003602081905260409091209081015460028201541415610878576108708a60006116cb565b935050610a75565b600085116108b75760405162461bcd60e51b815260040180806020018281038252602581526020018061248a6025913960400191505060405180910390fd5b60058101546001600160a01b031633141561094657600281015442906108e3908763ffffffff6110b216565b1180610906575060038101546002820154610904908763ffffffff6110b216565b145b6109415760405162461bcd60e51b815260040180806020018281038252602a8152602001806123ab602a913960400191505060405180910390fd5b6109ae565b60048101546001600160a01b03163314156109ae5760028101544290610972908763ffffffff6110b216565b106109ae5760405162461bcd60e51b815260040180806020018281038252602d81526020018061237e602d913960400191505060405180910390fd5b6060610a09600160029054906101000a90046001600160a01b03168b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508791506111139050565b915050610a65600160029054906101000a90046001600160a01b031689898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925087915061178c9050565b50610a708b876116cb565b945050505b50506001805461ff0019166101001790559695505050505050565b610aa0610a9b611a0d565b610b79565b610adb5760405162461bcd60e51b81526004018080602001828103825260308152602001806123026030913960400191505060405180910390fd5b60015460ff16610b29576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610b5c611a0d565b604080516001600160a01b039092168252519081900360200190a1565b6000610b8b818363ffffffff611a1116565b92915050565b60015460ff1690565b610baa610ba5611a0d565b611a78565b565b610bb7610a9b611a0d565b610bf25760405162461bcd60e51b81526004018080602001828103825260308152602001806123026030913960400191505060405180910390fd5b610bfb81611ac0565b50565b610c09610a9b611a0d565b610c445760405162461bcd60e51b81526004018080602001828103825260308152602001806123026030913960400191505060405180910390fd5b60015460ff1615610c8f576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610b5c611a0d565b6000818152600360205260408120600601548190819081908190819081908890600160a01b900460ff16610d37576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b5050506000958652505060036020819052604090942060058101546004820154825460068401546001850154600286015495909901546001600160a01b039485169a93851699929850931695509350565b60015460009060ff1615610dd6576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b038616610e31576040805162461bcd60e51b815260206004820152601a60248201527f73747265616d20746f20746865207a65726f2061646472657373000000000000604482015290519081900360640190fd5b6001600160a01b038616301415610e8f576040805162461bcd60e51b815260206004820152601d60248201527f73747265616d20746f2074686520636f6e747261637420697473656c66000000604482015290519081900360640190fd5b6001600160a01b038616331415610ee4576040805162461bcd60e51b815260206004820152601460248201527339ba3932b0b6903a37903a34329031b0b63632b960611b604482015290519081900360640190fd5b42831015610f235760405162461bcd60e51b815260040180806020018281038252602181526020018061235d6021913960400191505060405180910390fd5b828211610f615760405162461bcd60e51b81526004018080602001828103825260258152602001806124656025913960400191505060405180910390fd5b6002805460408051610100810182528881526020808201888152828401898152606084018981526001600160a01b03808f16608087019081523360a088019081528e831660c08901908152600160e08a0181815260008d815260039a8b90529b909b2099518a559651898801559451888c015592519587019590955593516004860180549186166001600160a01b0319928316179055905160058601805491861691831691909117905590516006909401805495511515600160a01b0260ff60a01b1995909416959091169490941792909216179091559154909161104c919063ffffffff6110b216565b600255604080516001600160a01b0387811682526020820189905281830187905260608201869052915191891691339184917fede16fa759a9d06c1022b933b4d4ed9b2cdcaafe19510813fdd430456f951b9a9181900360800190a49695505050505050565b60008282018381101561110c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b606080600061113384600201548560030154611b0890919063ffffffff16565b90506111598561114d83633b9aca0063ffffffff611b4a16565b9063ffffffff611ba316565b61116287611be5565b146111aa576040805162461bcd60e51b81526020600482015260136024820152720e4c2e8d2dee640c8de40dcdee840dac2e8c6d606b1b604482015290519081900360640190fd5b60405163a2866ea360e01b8152620104016004820181815230602484018190526060604485018181528b5160648701528b5191956001600160a01b038e169563a2866ea3959094938e93919260840190602085019080838360005b8381101561121d578181015183820152602001611205565b50505050905090810190601f16801561124a5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561126b57600080fd5b505af115801561127f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156112a857600080fd5b8101908080516040519392919084600160201b8211156112c757600080fd5b9083019060208201858111156112dc57600080fd5b8251600160201b8111828201881017156112f557600080fd5b82525081516020918201929091019080838360005b8381101561132257818101518382015260200161130a565b50505050905090810190601f16801561134f5780820380516001836020036101000a031916815260200191505b50604052505050905061137461136f600083611c1390919063ffffffff16565b611c6a565b50508654919550935061139661139186600063ffffffff611c1316565b611c94565b60200151146113d65760405162461bcd60e51b81526004018080602001828103825260228152602001806125a26022913960400191505060405180910390fd5b505094509492505050565b6000606061140786866113fd611391888763ffffffff611c1316565b6020015186611cd7565b905060608061141583611c6a565b5050915091506114236122e2565b61143761139183600163ffffffff611c1316565b80519091506001600160a01b031630146114825760405162461bcd60e51b81526004018080602001828103825260308152602001806124af6030913960400191505060405180910390fd5b600586015460408201516001600160a01b03909116906114a390600061208a565b6001600160a01b0316146114e85760405162461bcd60e51b81526004018080602001828103825260288152602001806125c46028913960400191505060405180910390fd5b600486015460408201516001600160a01b039091169061150990600161208a565b6001600160a01b03161461154e5760405162461bcd60e51b815260040180806020018281038252602b815260200180612332602b913960400191505060405180910390fd5b60068601546001600160a01b0316631f2ac16a61157561139186600063ffffffff611c1316565b60200151604080516001600160e01b031960e085901b16815260048101929092523060248301526001604483015260806064830152600060848301819052905160c48084019382900301818387803b1580156115d057600080fd5b505af11580156115e4573d6000803e3d6000fd5b505050506006860154604080516366ff548760e11b81526201010160048201818152602483019384528851604484015288516001600160a01b039095169463cdfea90e9492938a9391606490910190602085019080838360005b8381101561165657818101518382015260200161163e565b50505050905090810190601f1680156116835780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156116a357600080fd5b505af11580156116b7573d6000803e3d6000fd5b505050506020015198975050505050505050565b6000828152600360209081526040808320600481015460058201548351878152935192946001600160a01b0392831694919092169288927f78771645abf470107bd6a847c532dba992a0e2c0995d479ebe8153dea930543c928290030190a450505060009081526003602081905260408220828155600180820184905560028201849055918101929092556004820180546001600160a01b03199081169091556005830180549091169055600690910180546001600160a81b031916905590565b600060606117a886866113fd611391888763ffffffff611c1316565b90506060806117b683611c6a565b509193509150600090506117d3611391848363ffffffff611c1316565b6020015160048701549091506001600160a01b03166117fc61139184600063ffffffff611c1316565b516001600160a01b0316146118425760405162461bcd60e51b815260040180806020018281038252602e8152602001806124df602e913960400191505060405180910390fd5b60058601546001600160a01b031661186461139184600163ffffffff611c1316565b516001600160a01b0316146118aa5760405162461bcd60e51b815260040180806020018281038252602c815260200180612439602c913960400191505060405180910390fd5b600686015460408051630f9560b560e11b815260048101849052306024820152600160448201526080606482015260006084820181905291516001600160a01b0390931692631f2ac16a9260c48084019391929182900301818387803b15801561191357600080fd5b505af1158015611927573d6000803e3d6000fd5b505050506006860154604080516366ff548760e11b81526201010160048201818152602483019384528851604484015288516001600160a01b039095169463cdfea90e9492938a9391606490910190602085019080838360005b83811015611999578181015183820152602001611981565b50505050905090810190601f1680156119c65780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156119e657600080fd5b505af11580156119fa573d6000803e3d6000fd5b5060019c9b505050505050505050505050565b3390565b60006001600160a01b038216611a585760405162461bcd60e51b81526004018080602001828103825260228152602001806124176022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b611a8960008263ffffffff6120d916565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b611ad160008263ffffffff61214016565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b600061110c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506121c1565b600082611b5957506000610b8b565b82820282848281611b6657fe5b041461110c5760405162461bcd60e51b81526004018080602001828103825260218152602001806123f66021913960400191505060405180910390fd5b600061110c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612258565b6040810151606082015160009190611c0b8161114d84633b9aca0063ffffffff611b4a16565b949350505050565b602082810151908202830160400151830190821080611c635760405162461bcd60e51b815260040180806020018281038252602281526020018061263c6022913960400191505060405180910390fd5b5092915050565b60208101516040820151606083015160808401519284019491909301926001600160a01b03169190565b611c9c6122e2565b6000806060611caa856122bd565b604080516060810182526001600160a01b0390941684526020840192909252908201529350505050919050565b60405163a2866ea360e01b8152620101016004820181815230602484018190526060604485018181528851606487015288519195611e98956000956001600160a01b038d169563a2866ea395929490938d9360849091019060208501908083838d5b83811015611d51578181015183820152602001611d39565b50505050905090810190601f168015611d7e5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d9f57600080fd5b505af1158015611db3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611ddc57600080fd5b8101908080516040519392919084600160201b821115611dfb57600080fd5b908301906020820185811115611e1057600080fd5b8251600160201b811182820188101715611e2957600080fd5b82525081516020918201929091019080838360005b83811015611e56578181015183820152602001611e3e565b50505050905090810190601f168015611e835780820380516001836020036101000a031916815260200191505b50604052505050611c1390919063ffffffff16565b90506060806000611ea884611c6a565b9350509250925080600014611f04576040805162461bcd60e51b815260206004820152601d60248201527f6e6f6e7a65726f207075626c69632076616c7565207472616e73666572000000604482015290519081900360640190fd5b611f0d836122db565b600114611f61576040805162461bcd60e51b815260206004820152601f60248201527f496e636f7272656374206e756d626572206f6620696e707574206e6f74657300604482015290519081900360640190fd5b611f6a826122db565b600214611fbe576040805162461bcd60e51b815260206004820181905260248201527f496e636f7272656374206e756d626572206f66206f7574707574206e6f746573604482015290519081900360640190fd5b85611fd361139184600063ffffffff611c1316565b60200151146120135760405162461bcd60e51b81526004018080602001828103825260278152602001806125ec6027913960400191505060405180910390fd5b845461202961139185600063ffffffff611c1316565b602001511461207f576040805162461bcd60e51b815260206004820152601f60248201527f73747265616d206e6f746520696e2032206973206e6f7420636f727265637400604482015290519081900360640190fd5b505050949350505050565b6020828101519082028301610101015190808310611c635760405162461bcd60e51b815260040180806020018281038252605e81526020018061250d605e913960600191505060405180910390fd5b6120e38282611a11565b61211e5760405162461bcd60e51b81526004018080602001828103825260218152602001806123d56021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b61214a8282611a11565b1561219c576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b600081848411156122505760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122155781810151838201526020016121fd565b50505050905090810190601f1680156122425780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836122a75760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156122155781810151838201526020016121fd565b5060008385816122b357fe5b0495945050505050565b604081015160608201516001600160a01b0390911692909160800190565b6020015190565b604080516060808201835260008083526020830152918101919091529056fe506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c6573747265616d20726563697069656e742063616e27742076696577206e65772073747265616d206e6f746573746172742074696d65206265666f726520626c6f636b2e74696d657374616d70726563697069656e7420726563656976657320746f6f206d7563682066726f6d2063616e63656c6c6174696f6e73656e64657220726563656976657320746f6f206d7563682066726f6d2063616e63656c6c6174696f6e526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77526f6c65733a206163636f756e7420697320746865207a65726f206164647265737353747265616d2073656e64657220646f65736e2774206f776e207365636f6e64206f7574707574206e6f746553747265616d206475726174696f6e206e6f742067726561746572207468616e207a65726f63616e63656c6c6174696f6e2077697468207a65726f20756e636c61696d65642074696d656368616e6765206e6f746520696e2032206973206e6f74206f776e65642062792073747265616d20636f6e747261637453747265616d20726563697069656e7420646f65736e2774206f776e206669727374206f7574707574206e6f746561646472657373506f73206f7574206f6620626f756e6473202d2061646472657373506f73206d757374206265206c657373207468616e20746865206e756d626572206f662061646472657373657320746f20626520617070726f76656463616c6c6572206973206e6f74207468652073656e646572206f722074686520726563697069656e74206f66207468652073747265616d696e636f7272656374206e6f74696f6e616c206e6f746520696e2070726f6f66203173747265616d2073656e6465722063616e27742076696577206e65772073747265616d206e6f74657769746864726177206e6f746520696e2032206973206e6f74207468652073616d65206173203163616c6c6572206973206e6f742074686520726563697069656e74206f66207468652073747265616d415a54454320617272617920696e646578206973206f7574206f6620626f756e6473a265627a7a723158204b885b0fbc3e77ad991ce1dd489201ae8a4576ce93a7ba422ecf6cb1e2ceeb3464736f6c634300050f0032526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373',
+ '0x60806040523480156200001157600080fd5b50604051620031af380380620031af833981810160405260208110156200003757600080fd5b50516200005f620000506001600160e01b03620000fb16565b6001600160e01b03620000ff16565b6001805461ffff19166101001790556001600160a01b038116620000ca576040805162461bcd60e51b815260206004820181905260248201527f41434520636f6e747261637420697320746865207a65726f2061646472657373604482015290519081900360640190fd5b600180546001600160a01b03909216620100000262010000600160b01b031990921691909117815560025562000247565b3390565b6200011a8160006200015160201b620029261790919060201c565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6200016682826001600160e01b03620001de16565b15620001b9576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60006001600160a01b038216620002275760405162461bcd60e51b81526004018080602001828103825260228152602001806200318d6022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b612f3680620002576000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80635989dcde116100715780635989dcde146103035780635c975abb146104505780636ef8d66d1461045857806382dc1ec4146104605780638456cb5914610486578063894e9a0d1461048e576100a9565b80631468a5d4146100ae5780631e99d569146101e25780633bc9e403146101fc5780633f4ba83a146102d557806346fbf68e146102dd575b600080fd5b6101e0600480360360808110156100c457600080fd5b81359190810190604081016020820135600160201b8111156100e557600080fd5b8201836020820111156100f757600080fd5b803590602001918460018302840111600160201b8311171561011857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561016a57600080fd5b82018360208201111561017c57600080fd5b803590602001918460018302840111600160201b8311171561019d57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506104f5915050565b005b6101ea6107b2565b60408051918252519081900360200190f35b6102c16004803603608081101561021257600080fd5b81359190810190604081016020820135600160201b81111561023357600080fd5b82018360208201111561024557600080fd5b803590602001918460018302840111600160201b8311171561026657600080fd5b919390929091602081019035600160201b81111561028357600080fd5b82018360208201111561029557600080fd5b803590602001918460018302840111600160201b831117156102b657600080fd5b9193509150356107b8565b604080519115158252519081900360200190f35b6101e0610b51565b6102c1600480360360208110156102f357600080fd5b50356001600160a01b0316610c3a565b6101ea600480360360c081101561031957600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561034357600080fd5b82018360208201111561035557600080fd5b803590602001918460018302840111600160201b8311171561037657600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156103c857600080fd5b8201836020820111156103da57600080fd5b803590602001918460018302840111600160201b831117156103fb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550506001600160a01b038335169350505060208101359060400135610c52565b6102c1611014565b6101e061101d565b6101e06004803603602081101561047657600080fd5b50356001600160a01b031661102f565b6101e0611081565b6104ab600480360360208110156104a457600080fd5b5035611147565b604080516001600160a01b039889168152968816602088015286810195909552929095166060850152608084015260a083019390935260c082019290925290519081900360e00190f35b600154610100900460ff16610551576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6001805461ff00191690556000848152600360205260409020600601548490600160a01b900460ff166105c3576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b60008581526003602052604090206004015485906001600160a01b0316331461061d5760405162461bcd60e51b8152600401808060200182810382526029815260200180612eb76029913960400191505060405180910390fd5b600086815260036020526040902083610675576040805162461bcd60e51b81526020600482015260156024820152741e995c9bc81d985b1d59481dda5d1a191c985dd85b605a1b604482015290519081900360640190fd5b6002810154429061068c908663ffffffff61120b16565b106106de576040805162461bcd60e51b815260206004820181905260248201527f77697468647261772069732067726561746572207468616e20616c6c6f776564604482015290519081900360640190fd5b6001546000906106ff906201000090046001600160a01b031688878561126c565b90506000610724600160029054906101000a90046001600160a01b0316888486611555565b808455600284015490915061073f908763ffffffff61120b16565b60028401556004830154600584015460408051848152602081018a905281516001600160a01b0394851694909316928d927fc40560fdf83328f954941bff2b9141084d3c22e88c89a758557961e1966a57a9928290030190a450506001805461ff00191661010017905550505050505050565b60025481565b600154600090610100900460ff16610817576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6001805461ff00191690556000878152600360205260409020600601548790600160a01b900460ff16610889576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b60008881526003602052604090206005015488906001600160a01b03163314806108cc57506000818152600360205260409020600401546001600160a01b031633145b6109075760405162461bcd60e51b8152600401808060200182810382526037815260200180612de86037913960400191505060405180910390fd5b6000898152600360208190526040909120908101546002820154141561093a576109328a6000611829565b935050610b36565b600085116109795760405162461bcd60e51b8152600401808060200182810382526025815260200180612cb86025913960400191505060405180910390fd5b60058101546001600160a01b0316331415610a0857600281015442906109a5908763ffffffff61120b16565b11806109c85750600381015460028201546109c6908763ffffffff61120b16565b145b610a035760405162461bcd60e51b815260040180806020018281038252602a815260200180612bd9602a913960400191505060405180910390fd5b610a70565b60048101546001600160a01b0316331415610a705760028101544290610a34908763ffffffff61120b16565b10610a705760405162461bcd60e51b815260040180806020018281038252602d815260200180612b81602d913960400191505060405180910390fd5b6000610acb600160029054906101000a90046001600160a01b03168b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925087915061126c9050565b9050610b26600160029054906101000a90046001600160a01b031689898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508692508791506118ea9050565b50610b318b87611829565b945050505b50506001805461ff0019166101001790559695505050505050565b610b61610b5c611c39565b610c3a565b610b9c5760405162461bcd60e51b8152600401808060200182810382526030815260200180612ae16030913960400191505060405180910390fd5b60015460ff16610bea576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610c1d611c39565b604080516001600160a01b039092168252519081900360200190a1565b6000610c4c818363ffffffff611c3d16565b92915050565b60015460009060ff1615610ca0576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b038716610cfb576040805162461bcd60e51b815260206004820152601a60248201527f73747265616d20746f20746865207a65726f2061646472657373000000000000604482015290519081900360640190fd5b6001600160a01b038716301415610d59576040805162461bcd60e51b815260206004820152601d60248201527f73747265616d20746f2074686520636f6e747261637420697473656c66000000604482015290519081900360640190fd5b6001600160a01b038716331415610dae576040805162461bcd60e51b815260206004820152601460248201527339ba3932b0b6903a37903a34329031b0b63632b960611b604482015290519081900360640190fd5b42831015610ded5760405162461bcd60e51b8152600401808060200182810382526021815260200180612b606021913960400191505060405180910390fd5b828211610e2b5760405162461bcd60e51b8152600401808060200182810382526025815260200180612c936025913960400191505060405180910390fd5b6000610e508787600160029054906101000a90046001600160a01b0316338c8a611ca4565b9050600060025490506040518061010001604052808381526020018681526020018681526020018581526020018a6001600160a01b03168152602001336001600160a01b03168152602001876001600160a01b0316815260200160011515815250600360008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160060160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060e08201518160060160146101000a81548160ff021916908315150217905550905050610fac600160025461120b90919063ffffffff16565b600255604080516001600160a01b03888116825260208201859052818301889052606082018790529151918b1691339184917fede16fa759a9d06c1022b933b4d4ed9b2cdcaafe19510813fdd430456f951b9a9181900360800190a498975050505050505050565b60015460ff1690565b61102d611028611c39565b612257565b565b61103a610b5c611c39565b6110755760405162461bcd60e51b8152600401808060200182810382526030815260200180612ae16030913960400191505060405180910390fd5b61107e8161229f565b50565b61108c610b5c611c39565b6110c75760405162461bcd60e51b8152600401808060200182810382526030815260200180612ae16030913960400191505060405180910390fd5b60015460ff1615611112576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610c1d611c39565b6000818152600360205260408120600601548190819081908190819081908890600160a01b900460ff166111ba576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b5050506000958652505060036020819052604090942060058101546004820154825460068401546001850154600286015495909901546001600160a01b039485169a93851699929850931695509350565b600082820183811015611265576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008061128a836002015484600301546122e790919063ffffffff16565b90506112b0846112a483633b9aca0063ffffffff61232916565b9063ffffffff61238216565b6112b9866123c4565b14611301576040805162461bcd60e51b81526020600482015260136024820152720e4c2e8d2dee640c8de40dcdee840dac2e8c6d606b1b604482015290519081900360640190fd5b60405163a2866ea360e01b8152620104016004820181815230602484018190526060604485018181528a5160648701528a5191956001600160a01b038d169563a2866ea3959094938d93919260840190602085019080838360005b8381101561137457818101518382015260200161135c565b50505050905090810190601f1680156113a15780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156113c257600080fd5b505af11580156113d6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156113ff57600080fd5b8101908080516040519392919084600160201b82111561141e57600080fd5b90830190602082018581111561143357600080fd5b8251600160201b81118282018810171561144c57600080fd5b82525081516020918201929091019080838360005b83811015611479578181015183820152602001611461565b50505050905090810190601f1680156114a65780820380516001836020036101000a031916815260200191505b5060405250505090506060806114ce6114c96000856123f290919063ffffffff16565b612449565b5050875491935091506114f06114eb84600063ffffffff6123f216565b612473565b60200151146115305760405162461bcd60e51b8152600401808060200182810382526022815260200180612e1f6022913960400191505060405180910390fd5b6115446114eb82600063ffffffff6123f216565b602001519998505050505050505050565b60006060611565868686866124b6565b905060608061157383612449565b505091509150611581612ac1565b6115956114eb83600163ffffffff6123f216565b80519091506001600160a01b031630146115e05760405162461bcd60e51b8152600401808060200182810382526030815260200180612cdd6030913960400191505060405180910390fd5b600586015460408201516001600160a01b0390911690611601906000612869565b6001600160a01b0316146116465760405162461bcd60e51b8152600401808060200182810382526028815260200180612e686028913960400191505060405180910390fd5b600486015460408201516001600160a01b0390911690611667906001612869565b6001600160a01b0316146116ac5760405162461bcd60e51b815260040180806020018281038252602b815260200180612b11602b913960400191505060405180910390fd5b60068601546001600160a01b0316631f2ac16a6116d36114eb86600063ffffffff6123f216565b60200151604080516001600160e01b031960e085901b16815260048101929092523060248301526001604483015260806064830152600060848301819052905160c48084019382900301818387803b15801561172e57600080fd5b505af1158015611742573d6000803e3d6000fd5b505050506006860154604080516366ff548760e11b81526201010160048201818152602483019384528851604484015288516001600160a01b039095169463cdfea90e9492938a9391606490910190602085019080838360005b838110156117b457818101518382015260200161179c565b50505050905090810190601f1680156117e15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561180157600080fd5b505af1158015611815573d6000803e3d6000fd5b505050506020015198975050505050505050565b6000828152600360209081526040808320600481015460058201548351878152935192946001600160a01b0392831694919092169288927f78771645abf470107bd6a847c532dba992a0e2c0995d479ebe8153dea930543c928290030190a450505060009081526003602081905260408220828155600180820184905560028201849055918101929092556004820180546001600160a01b03199081169091556005830180549091169055600690910180546001600160a81b031916905590565b600060606118fa868686866124b6565b905060608061190883612449565b509193509150600090506119256114eb848363ffffffff6123f216565b602001519050611933612ac1565b6119476114eb84600063ffffffff6123f216565b9050611951612ac1565b6119656114eb85600163ffffffff6123f216565b600489015483519192506001600160a01b039182169116146119b85760405162461bcd60e51b815260040180806020018281038252602e815260200180612d5c602e913960400191505060405180910390fd5b600588015481516001600160a01b03908116911614611a085760405162461bcd60e51b815260040180806020018281038252602c815260200180612c67602c913960400191505060405180910390fd5b600488015460408301516001600160a01b0390911690611a29906000612869565b6001600160a01b031614611a6e5760405162461bcd60e51b815260040180806020018281038252602b815260200180612d31602b913960400191505060405180910390fd5b600588015460408201516001600160a01b0390911690611a8f906000612869565b6001600160a01b031614611ad45760405162461bcd60e51b8152600401808060200182810382526024815260200180612d0d6024913960400191505060405180910390fd5b600688015460408051630f9560b560e11b815260048101869052306024820152600160448201526080606482015260006084820181905291516001600160a01b0390931692631f2ac16a9260c48084019391929182900301818387803b158015611b3d57600080fd5b505af1158015611b51573d6000803e3d6000fd5b505050506006880154604080516366ff548760e11b81526201010160048201818152602483019384528a5160448401528a516001600160a01b039095169463cdfea90e9492938c9391606490910190602085019080838360005b83811015611bc3578181015183820152602001611bab565b50505050905090810190601f168015611bf05780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611c1057600080fd5b505af1158015611c24573d6000803e3d6000fd5b5060019e9d5050505050505050505050505050565b3390565b60006001600160a01b038216611c845760405162461bcd60e51b8152600401808060200182810382526022815260200180612c456022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b60006060856001600160a01b031663a2866ea362010101338b6040518463ffffffff1660e01b8152600401808462ffffff1662ffffff168152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611d31578181015183820152602001611d19565b50505050905090810190601f168015611d5e5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d7f57600080fd5b505af1158015611d93573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611dbc57600080fd5b8101908080516040519392919084600160201b821115611ddb57600080fd5b908301906020820185811115611df057600080fd5b8251600160201b811182820188101715611e0957600080fd5b82525081516020918201929091019080838360005b83811015611e36578181015183820152602001611e1e565b50505050905090810190601f168015611e635780820380516001836020036101000a031916815260200191505b5060405250505090506060611e826000836123f290919063ffffffff16565b90506060611e8f82612449565b5050915050611e9d816128b8565b600114611ef1576040805162461bcd60e51b815260206004820181905260248201527f496e636f7272656374206e756d626572206f66206f7574707574206e6f746573604482015290519081900360640190fd5b611ef9612ac1565b611f0d6114eb83600063ffffffff6123f216565b80519091506001600160a01b03163014611f585760405162461bcd60e51b815260040180806020018281038252602b815260200180612bae602b913960400191505060405180910390fd5b876001600160a01b0316611f7182604001516000612869565b6001600160a01b031614611fb65760405162461bcd60e51b8152600401808060200182810382526024815260200180612b3c6024913960400191505060405180910390fd5b866001600160a01b0316611fcf82604001516001612869565b6001600160a01b0316146120145760405162461bcd60e51b8152600401808060200182810382526027815260200180612e416027913960400191505060405180910390fd5b856001600160a01b0316630a60305a62010101863060018f6040518663ffffffff1660e01b8152600401808662ffffff1662ffffff16815260200180602001856001600160a01b03166001600160a01b031681526020018415151515815260200180602001838103835287818151815260200191508051906020019080838360005b838110156120ae578181015183820152602001612096565b50505050905090810190601f1680156120db5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561210e5781810151838201526020016120f6565b50505050905090810190601f16801561213b5780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561215f57600080fd5b505af1158015612173573d6000803e3d6000fd5b5050604080516366ff548760e11b81526201010160048201818152602483019384528851604484015288516001600160a01b038d16965063cdfea90e9550919389939192909160640190602085019080838360005b838110156121e05781810151838201526020016121c8565b50505050905090810190601f16801561220d5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561222d57600080fd5b505af1158015612241573d6000803e3d6000fd5b50505050602001519a9950505050505050505050565b61226860008263ffffffff6128bf16565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b6122b060008263ffffffff61292616565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b600061126583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506129a7565b60008261233857506000610c4c565b8282028284828161234557fe5b04146112655760405162461bcd60e51b8152600401808060200182810382526021815260200180612c246021913960400191505060405180910390fd5b600061126583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612a3e565b60408101516060820151600091906123ea816112a484633b9aca0063ffffffff61232916565b949350505050565b6020828101519082028301604001518301908210806124425760405162461bcd60e51b8152600401808060200182810382526022815260200180612ee06022913960400191505060405180910390fd5b5092915050565b60208101516040820151606083015160808401519284019491909301926001600160a01b03169190565b61247b612ac1565b600080606061248985612aa3565b604080516060810182526001600160a01b0390941684526020840192909252908201529350505050919050565b60405163a2866ea360e01b8152620101016004820181815230602484018190526060604485018181528851606487015288519195612677956000956001600160a01b038d169563a2866ea395929490938d9360849091019060208501908083838d5b83811015612530578181015183820152602001612518565b50505050905090810190601f16801561255d5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561257e57600080fd5b505af1158015612592573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156125bb57600080fd5b8101908080516040519392919084600160201b8211156125da57600080fd5b9083019060208201858111156125ef57600080fd5b8251600160201b81118282018810171561260857600080fd5b82525081516020918201929091019080838360005b8381101561263557818101518382015260200161261d565b50505050905090810190601f1680156126625780820380516001836020036101000a031916815260200191505b506040525050506123f290919063ffffffff16565b9050606080600061268784612449565b93505092509250806000146126e3576040805162461bcd60e51b815260206004820152601d60248201527f6e6f6e7a65726f207075626c69632076616c7565207472616e73666572000000604482015290519081900360640190fd5b6126ec836128b8565b600114612740576040805162461bcd60e51b815260206004820152601f60248201527f496e636f7272656374206e756d626572206f6620696e707574206e6f74657300604482015290519081900360640190fd5b612749826128b8565b60021461279d576040805162461bcd60e51b815260206004820181905260248201527f496e636f7272656374206e756d626572206f66206f7574707574206e6f746573604482015290519081900360640190fd5b856127b26114eb84600063ffffffff6123f216565b60200151146127f25760405162461bcd60e51b8152600401808060200182810382526027815260200180612e906027913960400191505060405180910390fd5b84546128086114eb85600063ffffffff6123f216565b602001511461285e576040805162461bcd60e51b815260206004820152601f60248201527f73747265616d206e6f746520696e2032206973206e6f7420636f727265637400604482015290519081900360640190fd5b505050949350505050565b60208281015190820283016101010151908083106124425760405162461bcd60e51b815260040180806020018281038252605e815260200180612d8a605e913960600191505060405180910390fd5b6020015190565b6128c98282611c3d565b6129045760405162461bcd60e51b8152600401808060200182810382526021815260200180612c036021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6129308282611c3d565b15612982576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008184841115612a365760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129fb5781810151838201526020016129e3565b50505050905090810190601f168015612a285780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183612a8d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156129fb5781810151838201526020016129e3565b506000838581612a9957fe5b0495945050505050565b604081015160608201516001600160a01b0390911692909160800190565b604080516060808201835260008083526020830152918101919091529056fe506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c6573747265616d20726563697069656e742063616e27742076696577206e65772073747265616d206e6f746573747265616d2073656e6465722063616e277420766965772073747265616d206e6f746573746172742074696d65206265666f726520626c6f636b2e74696d657374616d70726563697069656e7420726563656976657320746f6f206d7563682066726f6d2063616e63656c6c6174696f6e73747265616d206e6f7465206973206e6f74206f776e65642062792073747265616d20636f6e747261637473656e64657220726563656976657320746f6f206d7563682066726f6d2063616e63656c6c6174696f6e526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77526f6c65733a206163636f756e7420697320746865207a65726f206164647265737353747265616d2073656e64657220646f65736e2774206f776e207365636f6e64206f7574707574206e6f746553747265616d206475726174696f6e206e6f742067726561746572207468616e207a65726f63616e63656c6c6174696f6e2077697468207a65726f20756e636c61696d65642074696d656368616e6765206e6f746520696e2032206973206e6f74206f776e65642062792073747265616d20636f6e747261637473747265616d2073656e6465722063616e2774207669657720726566756e64206e6f746573747265616d20726563697069656e742063616e27742076696577207769746864726177616c206e6f746553747265616d20726563697069656e7420646f65736e2774206f776e206669727374206f7574707574206e6f746561646472657373506f73206f7574206f6620626f756e6473202d2061646472657373506f73206d757374206265206c657373207468616e20746865206e756d626572206f662061646472657373657320746f20626520617070726f76656463616c6c6572206973206e6f74207468652073656e646572206f722074686520726563697069656e74206f66207468652073747265616d696e636f7272656374206e6f74696f6e616c206e6f746520696e2070726f6f66203173747265616d20726563697069656e742063616e277420766965772073747265616d206e6f746573747265616d2073656e6465722063616e27742076696577206e65772073747265616d206e6f74657769746864726177206e6f746520696e2032206973206e6f74207468652073616d65206173203163616c6c6572206973206e6f742074686520726563697069656e74206f66207468652073747265616d415a54454320617272617920696e646578206973206f7574206f6620626f756e6473a265627a7a7231582082989ecb6430bf512f28d08363cc0a6bf2a065c4959092b9b848a6c99678da7964736f6c634300050f0032526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373',
deployedBytecode:
- '0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80635c975abb116100715780635c975abb146103035780636ef8d66d1461030b57806382dc1ec4146103135780638456cb5914610339578063894e9a0d14610341578063911ab96c146103a8576100a9565b80631468a5d4146100ae5780631e99d569146101e25780633bc9e403146101fc5780633f4ba83a146102d557806346fbf68e146102dd575b600080fd5b6101e0600480360360808110156100c457600080fd5b81359190810190604081016020820135600160201b8111156100e557600080fd5b8201836020820111156100f757600080fd5b803590602001918460018302840111600160201b8311171561011857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561016a57600080fd5b82018360208201111561017c57600080fd5b803590602001918460018302840111600160201b8311171561019d57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506103e8915050565b005b6101ea6106f0565b60408051918252519081900360200190f35b6102c16004803603608081101561021257600080fd5b81359190810190604081016020820135600160201b81111561023357600080fd5b82018360208201111561024557600080fd5b803590602001918460018302840111600160201b8311171561026657600080fd5b919390929091602081019035600160201b81111561028357600080fd5b82018360208201111561029557600080fd5b803590602001918460018302840111600160201b831117156102b657600080fd5b9193509150356106f6565b604080519115158252519081900360200190f35b6101e0610a90565b6102c1600480360360208110156102f357600080fd5b50356001600160a01b0316610b79565b6102c1610b91565b6101e0610b9a565b6101e06004803603602081101561032957600080fd5b50356001600160a01b0316610bac565b6101e0610bfe565b61035e6004803603602081101561035757600080fd5b5035610cc4565b604080516001600160a01b039889168152968816602088015286810195909552929095166060850152608084015260a083019390935260c082019290925290519081900360e00190f35b6101ea600480360360a08110156103be57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135610d88565b600154610100900460ff16610444576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6001805461ff0019811690915560ff1615610499576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6000848152600360205260409020600601548490600160a01b900460ff16610500576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b60008581526003602052604090206004015485906001600160a01b0316331461055a5760405162461bcd60e51b81526004018080602001828103825260298152602001806126136029913960400191505060405180910390fd5b6000868152600360205260409020836105b2576040805162461bcd60e51b81526020600482015260156024820152741e995c9bc81d985b1d59481dda5d1a191c985dd85b605a1b604482015290519081900360640190fd5b600281015442906105c9908663ffffffff6110b216565b1061061b576040805162461bcd60e51b815260206004820181905260248201527f77697468647261772069732067726561746572207468616e20616c6c6f776564604482015290519081900360640190fd5b60015460609061063c906201000090046001600160a01b0316888785611113565b9150506000610662600160029054906101000a90046001600160a01b03168884866113e1565b808455600284015490915061067d908763ffffffff6110b216565b60028401556004830154600584015460408051848152602081018a905281516001600160a01b0394851694909316928d927fc40560fdf83328f954941bff2b9141084d3c22e88c89a758557961e1966a57a9928290030190a450506001805461ff00191661010017905550505050505050565b60025481565b600154600090610100900460ff16610755576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6001805461ff00191690556000878152600360205260409020600601548790600160a01b900460ff166107c7576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b60008881526003602052604090206005015488906001600160a01b031633148061080a57506000818152600360205260409020600401546001600160a01b031633145b6108455760405162461bcd60e51b815260040180806020018281038252603781526020018061256b6037913960400191505060405180910390fd5b60008981526003602081905260409091209081015460028201541415610878576108708a60006116cb565b935050610a75565b600085116108b75760405162461bcd60e51b815260040180806020018281038252602581526020018061248a6025913960400191505060405180910390fd5b60058101546001600160a01b031633141561094657600281015442906108e3908763ffffffff6110b216565b1180610906575060038101546002820154610904908763ffffffff6110b216565b145b6109415760405162461bcd60e51b815260040180806020018281038252602a8152602001806123ab602a913960400191505060405180910390fd5b6109ae565b60048101546001600160a01b03163314156109ae5760028101544290610972908763ffffffff6110b216565b106109ae5760405162461bcd60e51b815260040180806020018281038252602d81526020018061237e602d913960400191505060405180910390fd5b6060610a09600160029054906101000a90046001600160a01b03168b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508791506111139050565b915050610a65600160029054906101000a90046001600160a01b031689898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086925087915061178c9050565b50610a708b876116cb565b945050505b50506001805461ff0019166101001790559695505050505050565b610aa0610a9b611a0d565b610b79565b610adb5760405162461bcd60e51b81526004018080602001828103825260308152602001806123026030913960400191505060405180910390fd5b60015460ff16610b29576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610b5c611a0d565b604080516001600160a01b039092168252519081900360200190a1565b6000610b8b818363ffffffff611a1116565b92915050565b60015460ff1690565b610baa610ba5611a0d565b611a78565b565b610bb7610a9b611a0d565b610bf25760405162461bcd60e51b81526004018080602001828103825260308152602001806123026030913960400191505060405180910390fd5b610bfb81611ac0565b50565b610c09610a9b611a0d565b610c445760405162461bcd60e51b81526004018080602001828103825260308152602001806123026030913960400191505060405180910390fd5b60015460ff1615610c8f576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610b5c611a0d565b6000818152600360205260408120600601548190819081908190819081908890600160a01b900460ff16610d37576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b5050506000958652505060036020819052604090942060058101546004820154825460068401546001850154600286015495909901546001600160a01b039485169a93851699929850931695509350565b60015460009060ff1615610dd6576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b038616610e31576040805162461bcd60e51b815260206004820152601a60248201527f73747265616d20746f20746865207a65726f2061646472657373000000000000604482015290519081900360640190fd5b6001600160a01b038616301415610e8f576040805162461bcd60e51b815260206004820152601d60248201527f73747265616d20746f2074686520636f6e747261637420697473656c66000000604482015290519081900360640190fd5b6001600160a01b038616331415610ee4576040805162461bcd60e51b815260206004820152601460248201527339ba3932b0b6903a37903a34329031b0b63632b960611b604482015290519081900360640190fd5b42831015610f235760405162461bcd60e51b815260040180806020018281038252602181526020018061235d6021913960400191505060405180910390fd5b828211610f615760405162461bcd60e51b81526004018080602001828103825260258152602001806124656025913960400191505060405180910390fd5b6002805460408051610100810182528881526020808201888152828401898152606084018981526001600160a01b03808f16608087019081523360a088019081528e831660c08901908152600160e08a0181815260008d815260039a8b90529b909b2099518a559651898801559451888c015592519587019590955593516004860180549186166001600160a01b0319928316179055905160058601805491861691831691909117905590516006909401805495511515600160a01b0260ff60a01b1995909416959091169490941792909216179091559154909161104c919063ffffffff6110b216565b600255604080516001600160a01b0387811682526020820189905281830187905260608201869052915191891691339184917fede16fa759a9d06c1022b933b4d4ed9b2cdcaafe19510813fdd430456f951b9a9181900360800190a49695505050505050565b60008282018381101561110c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b606080600061113384600201548560030154611b0890919063ffffffff16565b90506111598561114d83633b9aca0063ffffffff611b4a16565b9063ffffffff611ba316565b61116287611be5565b146111aa576040805162461bcd60e51b81526020600482015260136024820152720e4c2e8d2dee640c8de40dcdee840dac2e8c6d606b1b604482015290519081900360640190fd5b60405163a2866ea360e01b8152620104016004820181815230602484018190526060604485018181528b5160648701528b5191956001600160a01b038e169563a2866ea3959094938e93919260840190602085019080838360005b8381101561121d578181015183820152602001611205565b50505050905090810190601f16801561124a5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561126b57600080fd5b505af115801561127f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156112a857600080fd5b8101908080516040519392919084600160201b8211156112c757600080fd5b9083019060208201858111156112dc57600080fd5b8251600160201b8111828201881017156112f557600080fd5b82525081516020918201929091019080838360005b8381101561132257818101518382015260200161130a565b50505050905090810190601f16801561134f5780820380516001836020036101000a031916815260200191505b50604052505050905061137461136f600083611c1390919063ffffffff16565b611c6a565b50508654919550935061139661139186600063ffffffff611c1316565b611c94565b60200151146113d65760405162461bcd60e51b81526004018080602001828103825260228152602001806125a26022913960400191505060405180910390fd5b505094509492505050565b6000606061140786866113fd611391888763ffffffff611c1316565b6020015186611cd7565b905060608061141583611c6a565b5050915091506114236122e2565b61143761139183600163ffffffff611c1316565b80519091506001600160a01b031630146114825760405162461bcd60e51b81526004018080602001828103825260308152602001806124af6030913960400191505060405180910390fd5b600586015460408201516001600160a01b03909116906114a390600061208a565b6001600160a01b0316146114e85760405162461bcd60e51b81526004018080602001828103825260288152602001806125c46028913960400191505060405180910390fd5b600486015460408201516001600160a01b039091169061150990600161208a565b6001600160a01b03161461154e5760405162461bcd60e51b815260040180806020018281038252602b815260200180612332602b913960400191505060405180910390fd5b60068601546001600160a01b0316631f2ac16a61157561139186600063ffffffff611c1316565b60200151604080516001600160e01b031960e085901b16815260048101929092523060248301526001604483015260806064830152600060848301819052905160c48084019382900301818387803b1580156115d057600080fd5b505af11580156115e4573d6000803e3d6000fd5b505050506006860154604080516366ff548760e11b81526201010160048201818152602483019384528851604484015288516001600160a01b039095169463cdfea90e9492938a9391606490910190602085019080838360005b8381101561165657818101518382015260200161163e565b50505050905090810190601f1680156116835780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156116a357600080fd5b505af11580156116b7573d6000803e3d6000fd5b505050506020015198975050505050505050565b6000828152600360209081526040808320600481015460058201548351878152935192946001600160a01b0392831694919092169288927f78771645abf470107bd6a847c532dba992a0e2c0995d479ebe8153dea930543c928290030190a450505060009081526003602081905260408220828155600180820184905560028201849055918101929092556004820180546001600160a01b03199081169091556005830180549091169055600690910180546001600160a81b031916905590565b600060606117a886866113fd611391888763ffffffff611c1316565b90506060806117b683611c6a565b509193509150600090506117d3611391848363ffffffff611c1316565b6020015160048701549091506001600160a01b03166117fc61139184600063ffffffff611c1316565b516001600160a01b0316146118425760405162461bcd60e51b815260040180806020018281038252602e8152602001806124df602e913960400191505060405180910390fd5b60058601546001600160a01b031661186461139184600163ffffffff611c1316565b516001600160a01b0316146118aa5760405162461bcd60e51b815260040180806020018281038252602c815260200180612439602c913960400191505060405180910390fd5b600686015460408051630f9560b560e11b815260048101849052306024820152600160448201526080606482015260006084820181905291516001600160a01b0390931692631f2ac16a9260c48084019391929182900301818387803b15801561191357600080fd5b505af1158015611927573d6000803e3d6000fd5b505050506006860154604080516366ff548760e11b81526201010160048201818152602483019384528851604484015288516001600160a01b039095169463cdfea90e9492938a9391606490910190602085019080838360005b83811015611999578181015183820152602001611981565b50505050905090810190601f1680156119c65780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156119e657600080fd5b505af11580156119fa573d6000803e3d6000fd5b5060019c9b505050505050505050505050565b3390565b60006001600160a01b038216611a585760405162461bcd60e51b81526004018080602001828103825260228152602001806124176022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b611a8960008263ffffffff6120d916565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b611ad160008263ffffffff61214016565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b600061110c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506121c1565b600082611b5957506000610b8b565b82820282848281611b6657fe5b041461110c5760405162461bcd60e51b81526004018080602001828103825260218152602001806123f66021913960400191505060405180910390fd5b600061110c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612258565b6040810151606082015160009190611c0b8161114d84633b9aca0063ffffffff611b4a16565b949350505050565b602082810151908202830160400151830190821080611c635760405162461bcd60e51b815260040180806020018281038252602281526020018061263c6022913960400191505060405180910390fd5b5092915050565b60208101516040820151606083015160808401519284019491909301926001600160a01b03169190565b611c9c6122e2565b6000806060611caa856122bd565b604080516060810182526001600160a01b0390941684526020840192909252908201529350505050919050565b60405163a2866ea360e01b8152620101016004820181815230602484018190526060604485018181528851606487015288519195611e98956000956001600160a01b038d169563a2866ea395929490938d9360849091019060208501908083838d5b83811015611d51578181015183820152602001611d39565b50505050905090810190601f168015611d7e5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d9f57600080fd5b505af1158015611db3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611ddc57600080fd5b8101908080516040519392919084600160201b821115611dfb57600080fd5b908301906020820185811115611e1057600080fd5b8251600160201b811182820188101715611e2957600080fd5b82525081516020918201929091019080838360005b83811015611e56578181015183820152602001611e3e565b50505050905090810190601f168015611e835780820380516001836020036101000a031916815260200191505b50604052505050611c1390919063ffffffff16565b90506060806000611ea884611c6a565b9350509250925080600014611f04576040805162461bcd60e51b815260206004820152601d60248201527f6e6f6e7a65726f207075626c69632076616c7565207472616e73666572000000604482015290519081900360640190fd5b611f0d836122db565b600114611f61576040805162461bcd60e51b815260206004820152601f60248201527f496e636f7272656374206e756d626572206f6620696e707574206e6f74657300604482015290519081900360640190fd5b611f6a826122db565b600214611fbe576040805162461bcd60e51b815260206004820181905260248201527f496e636f7272656374206e756d626572206f66206f7574707574206e6f746573604482015290519081900360640190fd5b85611fd361139184600063ffffffff611c1316565b60200151146120135760405162461bcd60e51b81526004018080602001828103825260278152602001806125ec6027913960400191505060405180910390fd5b845461202961139185600063ffffffff611c1316565b602001511461207f576040805162461bcd60e51b815260206004820152601f60248201527f73747265616d206e6f746520696e2032206973206e6f7420636f727265637400604482015290519081900360640190fd5b505050949350505050565b6020828101519082028301610101015190808310611c635760405162461bcd60e51b815260040180806020018281038252605e81526020018061250d605e913960600191505060405180910390fd5b6120e38282611a11565b61211e5760405162461bcd60e51b81526004018080602001828103825260218152602001806123d56021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b61214a8282611a11565b1561219c576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b600081848411156122505760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122155781810151838201526020016121fd565b50505050905090810190601f1680156122425780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836122a75760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156122155781810151838201526020016121fd565b5060008385816122b357fe5b0495945050505050565b604081015160608201516001600160a01b0390911692909160800190565b6020015190565b604080516060808201835260008083526020830152918101919091529056fe506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c6573747265616d20726563697069656e742063616e27742076696577206e65772073747265616d206e6f746573746172742074696d65206265666f726520626c6f636b2e74696d657374616d70726563697069656e7420726563656976657320746f6f206d7563682066726f6d2063616e63656c6c6174696f6e73656e64657220726563656976657320746f6f206d7563682066726f6d2063616e63656c6c6174696f6e526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77526f6c65733a206163636f756e7420697320746865207a65726f206164647265737353747265616d2073656e64657220646f65736e2774206f776e207365636f6e64206f7574707574206e6f746553747265616d206475726174696f6e206e6f742067726561746572207468616e207a65726f63616e63656c6c6174696f6e2077697468207a65726f20756e636c61696d65642074696d656368616e6765206e6f746520696e2032206973206e6f74206f776e65642062792073747265616d20636f6e747261637453747265616d20726563697069656e7420646f65736e2774206f776e206669727374206f7574707574206e6f746561646472657373506f73206f7574206f6620626f756e6473202d2061646472657373506f73206d757374206265206c657373207468616e20746865206e756d626572206f662061646472657373657320746f20626520617070726f76656463616c6c6572206973206e6f74207468652073656e646572206f722074686520726563697069656e74206f66207468652073747265616d696e636f7272656374206e6f74696f6e616c206e6f746520696e2070726f6f66203173747265616d2073656e6465722063616e27742076696577206e65772073747265616d206e6f74657769746864726177206e6f746520696e2032206973206e6f74207468652073616d65206173203163616c6c6572206973206e6f742074686520726563697069656e74206f66207468652073747265616d415a54454320617272617920696e646578206973206f7574206f6620626f756e6473a265627a7a723158204b885b0fbc3e77ad991ce1dd489201ae8a4576ce93a7ba422ecf6cb1e2ceeb3464736f6c634300050f0032',
+ '0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80635989dcde116100715780635989dcde146103035780635c975abb146104505780636ef8d66d1461045857806382dc1ec4146104605780638456cb5914610486578063894e9a0d1461048e576100a9565b80631468a5d4146100ae5780631e99d569146101e25780633bc9e403146101fc5780633f4ba83a146102d557806346fbf68e146102dd575b600080fd5b6101e0600480360360808110156100c457600080fd5b81359190810190604081016020820135600160201b8111156100e557600080fd5b8201836020820111156100f757600080fd5b803590602001918460018302840111600160201b8311171561011857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561016a57600080fd5b82018360208201111561017c57600080fd5b803590602001918460018302840111600160201b8311171561019d57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506104f5915050565b005b6101ea6107b2565b60408051918252519081900360200190f35b6102c16004803603608081101561021257600080fd5b81359190810190604081016020820135600160201b81111561023357600080fd5b82018360208201111561024557600080fd5b803590602001918460018302840111600160201b8311171561026657600080fd5b919390929091602081019035600160201b81111561028357600080fd5b82018360208201111561029557600080fd5b803590602001918460018302840111600160201b831117156102b657600080fd5b9193509150356107b8565b604080519115158252519081900360200190f35b6101e0610b51565b6102c1600480360360208110156102f357600080fd5b50356001600160a01b0316610c3a565b6101ea600480360360c081101561031957600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561034357600080fd5b82018360208201111561035557600080fd5b803590602001918460018302840111600160201b8311171561037657600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156103c857600080fd5b8201836020820111156103da57600080fd5b803590602001918460018302840111600160201b831117156103fb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550506001600160a01b038335169350505060208101359060400135610c52565b6102c1611014565b6101e061101d565b6101e06004803603602081101561047657600080fd5b50356001600160a01b031661102f565b6101e0611081565b6104ab600480360360208110156104a457600080fd5b5035611147565b604080516001600160a01b039889168152968816602088015286810195909552929095166060850152608084015260a083019390935260c082019290925290519081900360e00190f35b600154610100900460ff16610551576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6001805461ff00191690556000848152600360205260409020600601548490600160a01b900460ff166105c3576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b60008581526003602052604090206004015485906001600160a01b0316331461061d5760405162461bcd60e51b8152600401808060200182810382526029815260200180612eb76029913960400191505060405180910390fd5b600086815260036020526040902083610675576040805162461bcd60e51b81526020600482015260156024820152741e995c9bc81d985b1d59481dda5d1a191c985dd85b605a1b604482015290519081900360640190fd5b6002810154429061068c908663ffffffff61120b16565b106106de576040805162461bcd60e51b815260206004820181905260248201527f77697468647261772069732067726561746572207468616e20616c6c6f776564604482015290519081900360640190fd5b6001546000906106ff906201000090046001600160a01b031688878561126c565b90506000610724600160029054906101000a90046001600160a01b0316888486611555565b808455600284015490915061073f908763ffffffff61120b16565b60028401556004830154600584015460408051848152602081018a905281516001600160a01b0394851694909316928d927fc40560fdf83328f954941bff2b9141084d3c22e88c89a758557961e1966a57a9928290030190a450506001805461ff00191661010017905550505050505050565b60025481565b600154600090610100900460ff16610817576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6001805461ff00191690556000878152600360205260409020600601548790600160a01b900460ff16610889576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b60008881526003602052604090206005015488906001600160a01b03163314806108cc57506000818152600360205260409020600401546001600160a01b031633145b6109075760405162461bcd60e51b8152600401808060200182810382526037815260200180612de86037913960400191505060405180910390fd5b6000898152600360208190526040909120908101546002820154141561093a576109328a6000611829565b935050610b36565b600085116109795760405162461bcd60e51b8152600401808060200182810382526025815260200180612cb86025913960400191505060405180910390fd5b60058101546001600160a01b0316331415610a0857600281015442906109a5908763ffffffff61120b16565b11806109c85750600381015460028201546109c6908763ffffffff61120b16565b145b610a035760405162461bcd60e51b815260040180806020018281038252602a815260200180612bd9602a913960400191505060405180910390fd5b610a70565b60048101546001600160a01b0316331415610a705760028101544290610a34908763ffffffff61120b16565b10610a705760405162461bcd60e51b815260040180806020018281038252602d815260200180612b81602d913960400191505060405180910390fd5b6000610acb600160029054906101000a90046001600160a01b03168b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925087915061126c9050565b9050610b26600160029054906101000a90046001600160a01b031689898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508692508791506118ea9050565b50610b318b87611829565b945050505b50506001805461ff0019166101001790559695505050505050565b610b61610b5c611c39565b610c3a565b610b9c5760405162461bcd60e51b8152600401808060200182810382526030815260200180612ae16030913960400191505060405180910390fd5b60015460ff16610bea576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610c1d611c39565b604080516001600160a01b039092168252519081900360200190a1565b6000610c4c818363ffffffff611c3d16565b92915050565b60015460009060ff1615610ca0576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b038716610cfb576040805162461bcd60e51b815260206004820152601a60248201527f73747265616d20746f20746865207a65726f2061646472657373000000000000604482015290519081900360640190fd5b6001600160a01b038716301415610d59576040805162461bcd60e51b815260206004820152601d60248201527f73747265616d20746f2074686520636f6e747261637420697473656c66000000604482015290519081900360640190fd5b6001600160a01b038716331415610dae576040805162461bcd60e51b815260206004820152601460248201527339ba3932b0b6903a37903a34329031b0b63632b960611b604482015290519081900360640190fd5b42831015610ded5760405162461bcd60e51b8152600401808060200182810382526021815260200180612b606021913960400191505060405180910390fd5b828211610e2b5760405162461bcd60e51b8152600401808060200182810382526025815260200180612c936025913960400191505060405180910390fd5b6000610e508787600160029054906101000a90046001600160a01b0316338c8a611ca4565b9050600060025490506040518061010001604052808381526020018681526020018681526020018581526020018a6001600160a01b03168152602001336001600160a01b03168152602001876001600160a01b0316815260200160011515815250600360008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160060160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060e08201518160060160146101000a81548160ff021916908315150217905550905050610fac600160025461120b90919063ffffffff16565b600255604080516001600160a01b03888116825260208201859052818301889052606082018790529151918b1691339184917fede16fa759a9d06c1022b933b4d4ed9b2cdcaafe19510813fdd430456f951b9a9181900360800190a498975050505050505050565b60015460ff1690565b61102d611028611c39565b612257565b565b61103a610b5c611c39565b6110755760405162461bcd60e51b8152600401808060200182810382526030815260200180612ae16030913960400191505060405180910390fd5b61107e8161229f565b50565b61108c610b5c611c39565b6110c75760405162461bcd60e51b8152600401808060200182810382526030815260200180612ae16030913960400191505060405180910390fd5b60015460ff1615611112576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610c1d611c39565b6000818152600360205260408120600601548190819081908190819081908890600160a01b900460ff166111ba576040805162461bcd60e51b81526020600482015260156024820152741cdd1c99585b48191bd95cc81b9bdd08195e1a5cdd605a1b604482015290519081900360640190fd5b5050506000958652505060036020819052604090942060058101546004820154825460068401546001850154600286015495909901546001600160a01b039485169a93851699929850931695509350565b600082820183811015611265576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008061128a836002015484600301546122e790919063ffffffff16565b90506112b0846112a483633b9aca0063ffffffff61232916565b9063ffffffff61238216565b6112b9866123c4565b14611301576040805162461bcd60e51b81526020600482015260136024820152720e4c2e8d2dee640c8de40dcdee840dac2e8c6d606b1b604482015290519081900360640190fd5b60405163a2866ea360e01b8152620104016004820181815230602484018190526060604485018181528a5160648701528a5191956001600160a01b038d169563a2866ea3959094938d93919260840190602085019080838360005b8381101561137457818101518382015260200161135c565b50505050905090810190601f1680156113a15780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156113c257600080fd5b505af11580156113d6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156113ff57600080fd5b8101908080516040519392919084600160201b82111561141e57600080fd5b90830190602082018581111561143357600080fd5b8251600160201b81118282018810171561144c57600080fd5b82525081516020918201929091019080838360005b83811015611479578181015183820152602001611461565b50505050905090810190601f1680156114a65780820380516001836020036101000a031916815260200191505b5060405250505090506060806114ce6114c96000856123f290919063ffffffff16565b612449565b5050875491935091506114f06114eb84600063ffffffff6123f216565b612473565b60200151146115305760405162461bcd60e51b8152600401808060200182810382526022815260200180612e1f6022913960400191505060405180910390fd5b6115446114eb82600063ffffffff6123f216565b602001519998505050505050505050565b60006060611565868686866124b6565b905060608061157383612449565b505091509150611581612ac1565b6115956114eb83600163ffffffff6123f216565b80519091506001600160a01b031630146115e05760405162461bcd60e51b8152600401808060200182810382526030815260200180612cdd6030913960400191505060405180910390fd5b600586015460408201516001600160a01b0390911690611601906000612869565b6001600160a01b0316146116465760405162461bcd60e51b8152600401808060200182810382526028815260200180612e686028913960400191505060405180910390fd5b600486015460408201516001600160a01b0390911690611667906001612869565b6001600160a01b0316146116ac5760405162461bcd60e51b815260040180806020018281038252602b815260200180612b11602b913960400191505060405180910390fd5b60068601546001600160a01b0316631f2ac16a6116d36114eb86600063ffffffff6123f216565b60200151604080516001600160e01b031960e085901b16815260048101929092523060248301526001604483015260806064830152600060848301819052905160c48084019382900301818387803b15801561172e57600080fd5b505af1158015611742573d6000803e3d6000fd5b505050506006860154604080516366ff548760e11b81526201010160048201818152602483019384528851604484015288516001600160a01b039095169463cdfea90e9492938a9391606490910190602085019080838360005b838110156117b457818101518382015260200161179c565b50505050905090810190601f1680156117e15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561180157600080fd5b505af1158015611815573d6000803e3d6000fd5b505050506020015198975050505050505050565b6000828152600360209081526040808320600481015460058201548351878152935192946001600160a01b0392831694919092169288927f78771645abf470107bd6a847c532dba992a0e2c0995d479ebe8153dea930543c928290030190a450505060009081526003602081905260408220828155600180820184905560028201849055918101929092556004820180546001600160a01b03199081169091556005830180549091169055600690910180546001600160a81b031916905590565b600060606118fa868686866124b6565b905060608061190883612449565b509193509150600090506119256114eb848363ffffffff6123f216565b602001519050611933612ac1565b6119476114eb84600063ffffffff6123f216565b9050611951612ac1565b6119656114eb85600163ffffffff6123f216565b600489015483519192506001600160a01b039182169116146119b85760405162461bcd60e51b815260040180806020018281038252602e815260200180612d5c602e913960400191505060405180910390fd5b600588015481516001600160a01b03908116911614611a085760405162461bcd60e51b815260040180806020018281038252602c815260200180612c67602c913960400191505060405180910390fd5b600488015460408301516001600160a01b0390911690611a29906000612869565b6001600160a01b031614611a6e5760405162461bcd60e51b815260040180806020018281038252602b815260200180612d31602b913960400191505060405180910390fd5b600588015460408201516001600160a01b0390911690611a8f906000612869565b6001600160a01b031614611ad45760405162461bcd60e51b8152600401808060200182810382526024815260200180612d0d6024913960400191505060405180910390fd5b600688015460408051630f9560b560e11b815260048101869052306024820152600160448201526080606482015260006084820181905291516001600160a01b0390931692631f2ac16a9260c48084019391929182900301818387803b158015611b3d57600080fd5b505af1158015611b51573d6000803e3d6000fd5b505050506006880154604080516366ff548760e11b81526201010160048201818152602483019384528a5160448401528a516001600160a01b039095169463cdfea90e9492938c9391606490910190602085019080838360005b83811015611bc3578181015183820152602001611bab565b50505050905090810190601f168015611bf05780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611c1057600080fd5b505af1158015611c24573d6000803e3d6000fd5b5060019e9d5050505050505050505050505050565b3390565b60006001600160a01b038216611c845760405162461bcd60e51b8152600401808060200182810382526022815260200180612c456022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b60006060856001600160a01b031663a2866ea362010101338b6040518463ffffffff1660e01b8152600401808462ffffff1662ffffff168152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611d31578181015183820152602001611d19565b50505050905090810190601f168015611d5e5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d7f57600080fd5b505af1158015611d93573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611dbc57600080fd5b8101908080516040519392919084600160201b821115611ddb57600080fd5b908301906020820185811115611df057600080fd5b8251600160201b811182820188101715611e0957600080fd5b82525081516020918201929091019080838360005b83811015611e36578181015183820152602001611e1e565b50505050905090810190601f168015611e635780820380516001836020036101000a031916815260200191505b5060405250505090506060611e826000836123f290919063ffffffff16565b90506060611e8f82612449565b5050915050611e9d816128b8565b600114611ef1576040805162461bcd60e51b815260206004820181905260248201527f496e636f7272656374206e756d626572206f66206f7574707574206e6f746573604482015290519081900360640190fd5b611ef9612ac1565b611f0d6114eb83600063ffffffff6123f216565b80519091506001600160a01b03163014611f585760405162461bcd60e51b815260040180806020018281038252602b815260200180612bae602b913960400191505060405180910390fd5b876001600160a01b0316611f7182604001516000612869565b6001600160a01b031614611fb65760405162461bcd60e51b8152600401808060200182810382526024815260200180612b3c6024913960400191505060405180910390fd5b866001600160a01b0316611fcf82604001516001612869565b6001600160a01b0316146120145760405162461bcd60e51b8152600401808060200182810382526027815260200180612e416027913960400191505060405180910390fd5b856001600160a01b0316630a60305a62010101863060018f6040518663ffffffff1660e01b8152600401808662ffffff1662ffffff16815260200180602001856001600160a01b03166001600160a01b031681526020018415151515815260200180602001838103835287818151815260200191508051906020019080838360005b838110156120ae578181015183820152602001612096565b50505050905090810190601f1680156120db5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561210e5781810151838201526020016120f6565b50505050905090810190601f16801561213b5780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561215f57600080fd5b505af1158015612173573d6000803e3d6000fd5b5050604080516366ff548760e11b81526201010160048201818152602483019384528851604484015288516001600160a01b038d16965063cdfea90e9550919389939192909160640190602085019080838360005b838110156121e05781810151838201526020016121c8565b50505050905090810190601f16801561220d5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561222d57600080fd5b505af1158015612241573d6000803e3d6000fd5b50505050602001519a9950505050505050505050565b61226860008263ffffffff6128bf16565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b6122b060008263ffffffff61292616565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b600061126583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506129a7565b60008261233857506000610c4c565b8282028284828161234557fe5b04146112655760405162461bcd60e51b8152600401808060200182810382526021815260200180612c246021913960400191505060405180910390fd5b600061126583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612a3e565b60408101516060820151600091906123ea816112a484633b9aca0063ffffffff61232916565b949350505050565b6020828101519082028301604001518301908210806124425760405162461bcd60e51b8152600401808060200182810382526022815260200180612ee06022913960400191505060405180910390fd5b5092915050565b60208101516040820151606083015160808401519284019491909301926001600160a01b03169190565b61247b612ac1565b600080606061248985612aa3565b604080516060810182526001600160a01b0390941684526020840192909252908201529350505050919050565b60405163a2866ea360e01b8152620101016004820181815230602484018190526060604485018181528851606487015288519195612677956000956001600160a01b038d169563a2866ea395929490938d9360849091019060208501908083838d5b83811015612530578181015183820152602001612518565b50505050905090810190601f16801561255d5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561257e57600080fd5b505af1158015612592573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156125bb57600080fd5b8101908080516040519392919084600160201b8211156125da57600080fd5b9083019060208201858111156125ef57600080fd5b8251600160201b81118282018810171561260857600080fd5b82525081516020918201929091019080838360005b8381101561263557818101518382015260200161261d565b50505050905090810190601f1680156126625780820380516001836020036101000a031916815260200191505b506040525050506123f290919063ffffffff16565b9050606080600061268784612449565b93505092509250806000146126e3576040805162461bcd60e51b815260206004820152601d60248201527f6e6f6e7a65726f207075626c69632076616c7565207472616e73666572000000604482015290519081900360640190fd5b6126ec836128b8565b600114612740576040805162461bcd60e51b815260206004820152601f60248201527f496e636f7272656374206e756d626572206f6620696e707574206e6f74657300604482015290519081900360640190fd5b612749826128b8565b60021461279d576040805162461bcd60e51b815260206004820181905260248201527f496e636f7272656374206e756d626572206f66206f7574707574206e6f746573604482015290519081900360640190fd5b856127b26114eb84600063ffffffff6123f216565b60200151146127f25760405162461bcd60e51b8152600401808060200182810382526027815260200180612e906027913960400191505060405180910390fd5b84546128086114eb85600063ffffffff6123f216565b602001511461285e576040805162461bcd60e51b815260206004820152601f60248201527f73747265616d206e6f746520696e2032206973206e6f7420636f727265637400604482015290519081900360640190fd5b505050949350505050565b60208281015190820283016101010151908083106124425760405162461bcd60e51b815260040180806020018281038252605e815260200180612d8a605e913960600191505060405180910390fd5b6020015190565b6128c98282611c3d565b6129045760405162461bcd60e51b8152600401808060200182810382526021815260200180612c036021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6129308282611c3d565b15612982576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60008184841115612a365760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129fb5781810151838201526020016129e3565b50505050905090810190601f168015612a285780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183612a8d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156129fb5781810151838201526020016129e3565b506000838581612a9957fe5b0495945050505050565b604081015160608201516001600160a01b0390911692909160800190565b604080516060808201835260008083526020830152918101919091529056fe506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c6573747265616d20726563697069656e742063616e27742076696577206e65772073747265616d206e6f746573747265616d2073656e6465722063616e277420766965772073747265616d206e6f746573746172742074696d65206265666f726520626c6f636b2e74696d657374616d70726563697069656e7420726563656976657320746f6f206d7563682066726f6d2063616e63656c6c6174696f6e73747265616d206e6f7465206973206e6f74206f776e65642062792073747265616d20636f6e747261637473656e64657220726563656976657320746f6f206d7563682066726f6d2063616e63656c6c6174696f6e526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77526f6c65733a206163636f756e7420697320746865207a65726f206164647265737353747265616d2073656e64657220646f65736e2774206f776e207365636f6e64206f7574707574206e6f746553747265616d206475726174696f6e206e6f742067726561746572207468616e207a65726f63616e63656c6c6174696f6e2077697468207a65726f20756e636c61696d65642074696d656368616e6765206e6f746520696e2032206973206e6f74206f776e65642062792073747265616d20636f6e747261637473747265616d2073656e6465722063616e2774207669657720726566756e64206e6f746573747265616d20726563697069656e742063616e27742076696577207769746864726177616c206e6f746553747265616d20726563697069656e7420646f65736e2774206f776e206669727374206f7574707574206e6f746561646472657373506f73206f7574206f6620626f756e6473202d2061646472657373506f73206d757374206265206c657373207468616e20746865206e756d626572206f662061646472657373657320746f20626520617070726f76656463616c6c6572206973206e6f74207468652073656e646572206f722074686520726563697069656e74206f66207468652073747265616d696e636f7272656374206e6f74696f6e616c206e6f746520696e2070726f6f66203173747265616d20726563697069656e742063616e277420766965772073747265616d206e6f746573747265616d2073656e6465722063616e27742076696577206e65772073747265616d206e6f74657769746864726177206e6f746520696e2032206973206e6f74207468652073616d65206173203163616c6c6572206973206e6f742074686520726563697069656e74206f66207468652073747265616d415a54454320617272617920696e646578206973206f7574206f6620626f756e6473a265627a7a7231582082989ecb6430bf512f28d08363cc0a6bf2a065c4959092b9b848a6c99678da7964736f6c634300050f0032',
linkReferences: {},
deployedLinkReferences: {},
};
diff --git a/packages/contract-artifacts/contracts/StreamUtilities.ts b/packages/contract-artifacts/contracts/StreamUtilities.ts
index 88a396f..e71d258 100644
--- a/packages/contract-artifacts/contracts/StreamUtilities.ts
+++ b/packages/contract-artifacts/contracts/StreamUtilities.ts
@@ -2,9 +2,9 @@ export default {
contractName: 'StreamUtilities',
abi: [],
bytecode:
- '0x60556023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72315820b0c8047152ae625605cc7c7239b8e424dfb7a37caeb5490776c10883d23299b664736f6c634300050f0032',
+ '0x60556023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72315820c8f9a590281f6d9170e715b7aeb1810d2783e72d630d1643d60a3320a9751d7664736f6c634300050f0032',
deployedBytecode:
- '0x73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72315820b0c8047152ae625605cc7c7239b8e424dfb7a37caeb5490776c10883d23299b664736f6c634300050f0032',
+ '0x73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72315820c8f9a590281f6d9170e715b7aeb1810d2783e72d630d1643d60a3320a9751d7664736f6c634300050f0032',
linkReferences: {},
deployedLinkReferences: {},
};
diff --git a/packages/contract-artifacts/package.json b/packages/contract-artifacts/package.json
index 781bb24..b51fae5 100644
--- a/packages/contract-artifacts/package.json
+++ b/packages/contract-artifacts/package.json
@@ -13,13 +13,14 @@
"@babel/preset-env": "^7.9.0",
"@babel/preset-typescript": "^7.9.0",
"@typescript-eslint/eslint-plugin-tslint": "^2.27.0",
- "eslint": "^5.15.3",
- "eslint-config-airbnb-base": "^13.1.0",
- "eslint-config-prettier": "^6.0.0",
- "eslint-plugin-import": "^2.20.2",
- "lint-staged": "^10.2.2",
+ "eslint": "^7.5.0",
+ "eslint-config-airbnb-base": "^14.2.0",
+ "eslint-config-prettier": "^6.11.0",
+ "eslint-plugin-import": "^2.22.0",
+ "eslint-plugin-prettier": "^3.1.4",
+ "lint-staged": "^10.2.11",
"shx": "^0.3.2",
- "typescript": "^3.8.3"
+ "typescript": "^3.9.7"
},
"engines": {
"node": ">=8.3"
@@ -53,7 +54,7 @@
"build:types": "tsc --emitDeclarationOnly",
"clean": "shx rm -rf ./lib",
"has:changed": "bash ../monorepo-scripts/ci/hasChanged.sh contract-artifacts",
- "lint": "eslint --config .eslintrc.js --ext .js,.ts . ",
+ "lint": "eslint --config .eslintrc.js --ext .ts . ",
"watch": "yarn build --watch"
},
"config": {
diff --git a/packages/contracts/contracts/AZTEC/Imports.sol b/packages/contracts/contracts/AZTEC/Imports.sol
deleted file mode 100644
index 24da250..0000000
--- a/packages/contracts/contracts/AZTEC/Imports.sol
+++ /dev/null
@@ -1,24 +0,0 @@
-pragma solidity ^0.5.11;
-
-import "@aztec/protocol/contracts/ACE/ACE.sol";
-import "@aztec/protocol/contracts/ACE/noteRegistry/epochs/201912/base/FactoryBase201912.sol";
-import "@aztec/protocol/contracts/ACE/validators/joinSplit/JoinSplit.sol";
-import "@aztec/protocol/contracts/ACE/validators/dividend/Dividend.sol";
-import "@aztec/protocol/contracts/ERC1724/ZkAsset.sol";
-
-
-// You might think this file is a bit odd, but let me explain.
-// We only use some contracts in our tests, which means Truffle
-// will not compile it for us, because it is from an external
-// dependency.
-//
-// We are now left with three options:
-// - Copy/paste these contracts
-// - Run the tests with `truffle compile --all` on
-// - Or trick Truffle by claiming we use it in a Solidity test
-//
-// You know which one I went for.
-
-contract Imports {
- constructor() public {}
-}
diff --git a/packages/contracts/contracts/NoteStream.sol b/packages/contracts/contracts/NoteStream.sol
index e3047fa..80e5842 100644
--- a/packages/contracts/contracts/NoteStream.sol
+++ b/packages/contracts/contracts/NoteStream.sol
@@ -1,11 +1,11 @@
pragma solidity ^0.5.11;
-import "@openzeppelin/contracts/lifecycle/Pausable.sol";
-import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
+import '@openzeppelin/contracts/lifecycle/Pausable.sol';
+import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
-import "./StreamUtilities.sol";
+import './StreamUtilities.sol';
-import "./Types.sol";
+import './Types.sol';
/**
@@ -65,7 +65,7 @@ contract NoteStream is Pausable, ReentrancyGuard {
require(
msg.sender == streams[streamId].sender ||
msg.sender == streams[streamId].recipient,
- "caller is not the sender or the recipient of the stream"
+ 'caller is not the sender or the recipient of the stream'
);
_;
}
@@ -76,7 +76,7 @@ contract NoteStream is Pausable, ReentrancyGuard {
modifier onlyRecipient(uint256 streamId) {
require(
msg.sender == streams[streamId].recipient,
- "caller is not the recipient of the stream"
+ 'caller is not the recipient of the stream'
);
_;
}
@@ -85,7 +85,7 @@ contract NoteStream is Pausable, ReentrancyGuard {
* @dev Throws if the provided id does not point to a valid stream.
*/
modifier streamExists(uint256 streamId) {
- require(streams[streamId].isEntity, "stream does not exist");
+ require(streams[streamId].isEntity, 'stream does not exist');
_;
}
@@ -94,7 +94,7 @@ contract NoteStream is Pausable, ReentrancyGuard {
constructor(address _aceContractAddress) public {
require(
_aceContractAddress != address(0x00),
- "ACE contract is the zero address"
+ 'ACE contract is the zero address'
);
aceContractAddress = _aceContractAddress;
nextStreamId = 1;
@@ -144,7 +144,7 @@ contract NoteStream is Pausable, ReentrancyGuard {
* Throws if the contract is not allowed to transfer enough tokens.
* Throws if there is a token transfer failure.
* @param recipient The address towards which the money is streamed.
- * @param noteHash The note of a zkAsset to be streamed.
+ * @param proof The JoinSplit proof transfering a zkAsset to be streamed.
* @param tokenAddress The zkAsset to use as streaming currency.
* @param startTime The unix timestamp for when the stream starts.
* @param stopTime The unix timestamp for when the stream stops.
@@ -152,24 +152,35 @@ contract NoteStream is Pausable, ReentrancyGuard {
*/
function createStream(
address recipient,
- bytes32 noteHash,
+ bytes memory proof,
+ bytes memory proofSignature,
address tokenAddress,
uint256 startTime,
uint256 stopTime
) public whenNotPaused returns (uint256) {
- require(recipient != address(0x00), "stream to the zero address");
- require(recipient != address(this), "stream to the contract itself");
- require(recipient != msg.sender, "stream to the caller");
+ require(recipient != address(0x00), 'stream to the zero address');
+ require(recipient != address(this), 'stream to the contract itself');
+ require(recipient != msg.sender, 'stream to the caller');
require(
startTime >= block.timestamp, // solium-disable-line security/no-block-members
- "start time before block.timestamp"
+ 'start time before block.timestamp'
+ );
+ require(stopTime > startTime, 'Stream duration not greater than zero');
+
+ // Transfer the ZkAsset to the streaming contract
+ bytes32 streamNoteHash = StreamUtilities._processDeposit(
+ proof,
+ proofSignature,
+ aceContractAddress,
+ msg.sender,
+ recipient,
+ tokenAddress
);
- require(stopTime > startTime, "Stream duration not greater than zero");
/* Create and store the stream object. */
uint256 streamId = nextStreamId;
streams[streamId] = Types.AztecStream({
- noteHash: noteHash,
+ noteHash: streamNoteHash,
sender: msg.sender,
recipient: recipient,
startTime: startTime,
@@ -187,7 +198,7 @@ contract NoteStream is Pausable, ReentrancyGuard {
msg.sender,
recipient,
tokenAddress,
- noteHash,
+ streamNoteHash,
startTime,
stopTime
);
@@ -200,27 +211,21 @@ contract NoteStream is Pausable, ReentrancyGuard {
bytes memory _proof1, // Dividend Proof
bytes memory _proof2, // Join-Split Proof
uint256 _streamDurationToWithdraw
- )
- public
- nonReentrant
- streamExists(streamId)
- onlyRecipient(streamId)
- {
+ ) public nonReentrant streamExists(streamId) onlyRecipient(streamId) {
Types.AztecStream storage stream = streams[streamId];
// First check that this isn't a zero value withdrawal
- require(_streamDurationToWithdraw > 0, "zero value withdrawal");
+ require(_streamDurationToWithdraw > 0, 'zero value withdrawal');
// Check that fraction to withdraw isn't greater than fraction of time passed
require(
stream.lastWithdrawTime.add(_streamDurationToWithdraw) <
block.timestamp, // solium-disable-line security/no-block-members
- "withdraw is greater than allowed"
+ 'withdraw is greater than allowed'
);
// Check that value of withdrawal matches the fraction given by the above timestamp
- (, bytes memory _proof1OutputNotes) = StreamUtilities
- ._validateRatioProof(
+ bytes32 withdrawalNoteHash = StreamUtilities._validateRatioProof(
aceContractAddress,
_proof1,
_streamDurationToWithdraw,
@@ -232,7 +237,7 @@ contract NoteStream is Pausable, ReentrancyGuard {
bytes32 newNoteHash = StreamUtilities._processWithdrawal(
aceContractAddress,
_proof2,
- _proof1OutputNotes,
+ withdrawalNoteHash,
stream
);
@@ -283,7 +288,7 @@ contract NoteStream is Pausable, ReentrancyGuard {
}
// We require the denominator of ratio proof to be nonzero
- require(_unclaimedTime > 0, "cancellation with zero unclaimed time");
+ require(_unclaimedTime > 0, 'cancellation with zero unclaimed time');
// Otherwise check that cancelling party isn't trying to scam the other
// Each party can only cancel from a timestamp favourable to the other party.
@@ -296,20 +301,19 @@ contract NoteStream is Pausable, ReentrancyGuard {
stream.lastWithdrawTime.add(_unclaimedTime) > block.timestamp ||
stream.lastWithdrawTime.add(_unclaimedTime) ==
stream.stopTime,
- "sender receives too much from cancellation"
+ 'sender receives too much from cancellation'
);
} else if (msg.sender == stream.recipient) {
// Recipient can only cancel from a timestamp which has already passed
require(
// solium-disable-next-line security/no-block-members
stream.lastWithdrawTime.add(_unclaimedTime) < block.timestamp,
- "recipient receives too much from cancellation"
+ 'recipient receives too much from cancellation'
);
}
// Check that value of withdrawal matches the fraction given by the above timestamp
- (, bytes memory _proof1OutputNotes) = StreamUtilities
- ._validateRatioProof(
+ bytes32 withdrawalNoteHash = StreamUtilities._validateRatioProof(
aceContractAddress,
_proof1,
_unclaimedTime,
@@ -318,10 +322,10 @@ contract NoteStream is Pausable, ReentrancyGuard {
// Check that cancellation transaction is valid and perform transfer
// i.e. Each party receives a note of correct value
- StreamUtilities._processCancelation(
+ StreamUtilities._processCancellation(
aceContractAddress,
_proof2,
- _proof1OutputNotes,
+ withdrawalNoteHash,
stream
);
diff --git a/packages/contracts/contracts/StreamUtilities.sol b/packages/contracts/contracts/StreamUtilities.sol
index b1ba4ff..2ff44a6 100644
--- a/packages/contracts/contracts/StreamUtilities.sol
+++ b/packages/contracts/contracts/StreamUtilities.sol
@@ -1,13 +1,13 @@
pragma solidity ^0.5.11;
-import "@openzeppelin/contracts/math/SafeMath.sol";
+import '@openzeppelin/contracts/math/SafeMath.sol';
-import "@aztec/protocol/contracts/interfaces/IACE.sol";
-import "@aztec/protocol/contracts/interfaces/IZkAsset.sol";
-import "@aztec/protocol/contracts/libs/NoteUtils.sol";
-import "@aztec/protocol/contracts/libs/MetaDataUtils.sol";
+import '@aztec/protocol/contracts/interfaces/IACE.sol';
+import '@aztec/protocol/contracts/interfaces/IZkAsset.sol';
+import '@aztec/protocol/contracts/libs/NoteUtils.sol';
+import '@aztec/protocol/contracts/libs/MetaDataUtils.sol';
-import "./Types.sol";
+import './Types.sol';
library StreamUtilities {
@@ -51,24 +51,82 @@ library StreamUtilities {
return za.mul(scalingFactor).div(zb);
}
+ function _processDeposit(
+ bytes memory _proof,
+ bytes memory _proofSignature,
+ address _aceContractAddress,
+ address _sender,
+ address _recipient,
+ address _tokenAddress
+ ) internal returns (bytes32 streamNoteHash) {
+ // Validate Join-Split proof
+ bytes memory proofOutputs = IACE(_aceContractAddress).validateProof(
+ JOIN_SPLIT_PROOF,
+ msg.sender,
+ _proof
+ );
+
+ bytes memory proofOutput = proofOutputs.get(0);
+
+ // Extract notes used in proof
+ (, bytes memory _proofOutputNotes, , ) = proofOutput
+ .extractProofOutput();
+
+ // Ensure that there is only a single output note to avoid loss of funds
+ require(
+ _proofOutputNotes.getLength() == 1,
+ 'Incorrect number of output notes'
+ );
+
+ Note memory streamNote = _noteCoderToStruct(_proofOutputNotes.get(0));
+
+ // Require that stream note is owned by contract
+ require(
+ streamNote.owner == address(this),
+ 'stream note is not owned by stream contract'
+ );
+
+ // Require that sender and receiver have view access to stream note
+ require(
+ MetaDataUtils.extractAddress(streamNote.metaData, 0) == _sender,
+ "stream sender can't view stream note"
+ );
+ require(
+ MetaDataUtils.extractAddress(streamNote.metaData, 1) == _recipient,
+ "stream recipient can't view stream note"
+ );
+
+ // Approve contract to place user's zkAssets into the stream note
+ IZkAsset(_tokenAddress).approveProof(
+ JOIN_SPLIT_PROOF,
+ proofOutputs,
+ address(this),
+ true,
+ _proofSignature
+ );
+
+ // Send transfer
+ IZkAsset(_tokenAddress).confidentialTransferFrom(
+ JOIN_SPLIT_PROOF,
+ proofOutput
+ );
+
+ // Return stream note hash
+ streamNoteHash = streamNote.noteHash;
+ }
+
function _validateRatioProof(
address _aceContractAddress,
bytes memory _proof1,
uint256 _withdrawDuration,
Types.AztecStream storage _stream
- )
- internal
- returns (
- bytes memory _proof1InputNotes,
- bytes memory _proof1OutputNotes
- )
- {
+ ) internal returns (bytes32 withdrawalNoteHash) {
// Check that ratio of notes match that given by fraction of remaining time to withdraw
uint256 totalTime = _stream.stopTime.sub(_stream.lastWithdrawTime);
require(
getRatio(_proof1) ==
totalTime.mul(scalingFactor).div(_withdrawDuration),
- "ratios do not match"
+ 'ratios do not match'
);
// Validate ratio proof
@@ -77,17 +135,23 @@ library StreamUtilities {
address(this),
_proof1
);
- (_proof1InputNotes, _proof1OutputNotes, , ) = _proof1Outputs
- .get(0)
- .extractProofOutput();
+ (
+ bytes memory _proof1InputNotes,
+ bytes memory _proof1OutputNotes,
+ ,
+
+ ) = _proof1Outputs.get(0).extractProofOutput();
// Make sure that recipient has provided the note on the contract as input
// This prevents recipient using a larger note for this proof to allow a larger withdrawal
require(
_noteCoderToStruct(_proof1InputNotes.get(0)).noteHash ==
_stream.noteHash,
- "incorrect notional note in proof 1"
+ 'incorrect notional note in proof 1'
);
+
+ withdrawalNoteHash = _noteCoderToStruct(_proof1OutputNotes.get(0))
+ .noteHash;
}
function _validateJoinSplitProof(
@@ -109,45 +173,45 @@ library StreamUtilities {
int256 publicValue
) = proof2Outputs.extractProofOutput();
- require(publicValue == 0, "nonzero public value transfer");
+ require(publicValue == 0, 'nonzero public value transfer');
// Ensure stream note is the only input note
require(
_proof2InputNotes.getLength() == 1,
- "Incorrect number of input notes"
+ 'Incorrect number of input notes'
);
// Ensure that there isn't a third output note used to avoid the below checks
require(
_proof2OutputNotes.getLength() == 2,
- "Incorrect number of output notes"
+ 'Incorrect number of output notes'
);
// Requires that output note respects dividend proof
require(
_noteCoderToStruct(_proof2OutputNotes.get(0)).noteHash ==
_withdrawalNoteHash,
- "withdraw note in 2 is not the same as 1"
+ 'withdraw note in 2 is not the same as 1'
);
// Require that input note is stream note
require(
_noteCoderToStruct(_proof2InputNotes.get(0)).noteHash ==
_stream.noteHash,
- "stream note in 2 is not correct"
+ 'stream note in 2 is not correct'
);
}
function _processWithdrawal(
address _aceContractAddress,
bytes memory _proof2,
- bytes memory _proof1OutputNotes,
+ bytes32 _withdrawalNoteHash,
Types.AztecStream storage _stream
) internal returns (bytes32) {
bytes memory proof2Outputs = _validateJoinSplitProof(
_aceContractAddress,
_proof2,
- _noteCoderToStruct(_proof1OutputNotes.get(0)).noteHash, // withdrawal note hash
+ _withdrawalNoteHash,
_stream
);
@@ -165,7 +229,7 @@ library StreamUtilities {
// Require that change note is owned by contract
require(
newStreamNote.owner == address(this),
- "change note in 2 is not owned by stream contract"
+ 'change note in 2 is not owned by stream contract'
);
// Require that sender and receiver have view access to change note
@@ -185,7 +249,7 @@ library StreamUtilities {
_noteCoderToStruct(_proof2InputNotes.get(0)).noteHash,
address(this),
true,
- ""
+ ''
);
// Send transfer
@@ -198,16 +262,16 @@ library StreamUtilities {
return newStreamNote.noteHash;
}
- function _processCancelation(
+ function _processCancellation(
address _aceContractAddress,
bytes memory _proof2,
- bytes memory _proof1OutputNotes,
+ bytes32 _withdrawalNoteHash,
Types.AztecStream storage _stream
) internal returns (bool) {
bytes memory proof2Outputs = _validateJoinSplitProof(
_aceContractAddress,
_proof2,
- _noteCoderToStruct(_proof1OutputNotes.get(0)).noteHash, // withdrawal note hash
+ _withdrawalNoteHash,
_stream
);
// Extract notes used in proof
@@ -221,24 +285,39 @@ library StreamUtilities {
bytes32 inputNoteHash = _noteCoderToStruct(_proof2InputNotes.get(0))
.noteHash;
+ Note memory withdrawalNote = _noteCoderToStruct(
+ _proof2OutputNotes.get(0)
+ );
+ Note memory refundNote = _noteCoderToStruct(_proof2OutputNotes.get(1));
+
// Require that each participant owns an output note
require(
- _noteCoderToStruct(_proof2OutputNotes.get(0)).owner ==
- _stream.recipient,
+ withdrawalNote.owner == _stream.recipient,
"Stream recipient doesn't own first output note"
);
require(
- _noteCoderToStruct(_proof2OutputNotes.get(1)).owner ==
- _stream.sender,
+ refundNote.owner == _stream.sender,
"Stream sender doesn't own second output note"
);
+ // Require that sender and receiver have view access to their notes
+ require(
+ MetaDataUtils.extractAddress(withdrawalNote.metaData, 0) ==
+ _stream.recipient,
+ "stream recipient can't view withdrawal note"
+ );
+ require(
+ MetaDataUtils.extractAddress(refundNote.metaData, 0) ==
+ _stream.sender,
+ "stream sender can't view refund note"
+ );
+
// Approve contract to spend with stream note
IZkAsset(_stream.tokenAddress).confidentialApprove(
inputNoteHash,
address(this),
true,
- ""
+ ''
);
// Send transfer
diff --git a/packages/contracts/contracts/mocks/StreamUtilitiesMock.sol b/packages/contracts/contracts/mocks/StreamUtilitiesMock.sol
index 26ada8f..c48aa0d 100644
--- a/packages/contracts/contracts/mocks/StreamUtilitiesMock.sol
+++ b/packages/contracts/contracts/mocks/StreamUtilitiesMock.sol
@@ -1,20 +1,24 @@
pragma solidity ^0.5.11;
pragma experimental ABIEncoderV2;
-import "../StreamUtilities.sol";
+import '../StreamUtilities.sol';
contract StreamUtilitiesMock {
-
// The provided struct object is stored here as StreamUtilities expects a storage variable.
Types.AztecStream public stream;
+ event ValidateRatioProof(bytes32 withdrawalNoteHash);
+ event ValidateJoinSplitProof(bytes32 withdrawalNoteHash);
+ event ProcessDeposit(bytes32 streamNoteHash);
+ event ProcessWithdrawal(bytes32 newStreamNoteHash);
+ event ProcessCancellation(bool cancellationSuccess);
function getRatio(bytes memory _proofData)
public
pure
returns (uint256 ratio)
{
- return StreamUtilities.getRatio(_proofData);
+ return StreamUtilities.getRatio(_proofData);
}
function validateRatioProof(
@@ -22,12 +26,15 @@ contract StreamUtilitiesMock {
bytes memory _proof1,
uint256 _withdrawDuration,
Types.AztecStream memory _stream
- )
- public
- returns (bytes memory, bytes memory)
- {
+ ) public returns (bytes32) {
stream = _stream;
- return StreamUtilities._validateRatioProof(_aceContractAddress, _proof1, _withdrawDuration, stream);
+ bytes32 withdrawalNoteHash = StreamUtilities._validateRatioProof(
+ _aceContractAddress,
+ _proof1,
+ _withdrawDuration,
+ stream
+ );
+ emit ValidateRatioProof(withdrawalNoteHash);
}
function validateJoinSplitProof(
@@ -35,28 +42,66 @@ contract StreamUtilitiesMock {
bytes memory _proof2,
bytes32 _withdrawalNoteHash,
Types.AztecStream memory _stream
- ) public returns (bytes memory proof2Outputs) {
+ ) public returns (bytes memory) {
stream = _stream;
- return StreamUtilities._validateJoinSplitProof(_aceContractAddress, _proof2, _withdrawalNoteHash, stream);
+ bytes memory proofOutputs =
+ StreamUtilities._validateJoinSplitProof(
+ _aceContractAddress,
+ _proof2,
+ _withdrawalNoteHash,
+ stream
+ );
+ }
+
+ function processDeposit(
+ bytes memory _proof,
+ bytes memory _proofSignature,
+ address _aceContractAddress,
+ address _sender,
+ address _recipient,
+ address _tokenAddress
+ ) public returns (bytes32) {
+ bytes32 newStreamNoteHash = StreamUtilities._processDeposit(
+ _proof,
+ _proofSignature,
+ _aceContractAddress,
+ _sender,
+ _recipient,
+ _tokenAddress
+ );
+ emit ProcessDeposit(newStreamNoteHash);
}
function processWithdrawal(
address _aceContractAddress,
bytes memory _proof2,
- bytes memory _proof1OutputNotes,
+ bytes32 _withdrawalNoteHash,
Types.AztecStream memory _stream
) public returns (bytes32) {
stream = _stream;
- return StreamUtilities._processWithdrawal(_aceContractAddress, _proof2, _proof1OutputNotes, stream);
+ bytes32 newStreamNoteHash = StreamUtilities._processWithdrawal(
+ _aceContractAddress,
+ _proof2,
+ _withdrawalNoteHash,
+ stream
+ );
+ emit ProcessWithdrawal(newStreamNoteHash);
}
- function processCancelation(
+ function processCancellation(
address _aceContractAddress,
bytes memory _proof2,
- bytes memory _proof1OutputNotes,
+ bytes32 _proof1OutputNotes,
Types.AztecStream memory _stream
) public returns (bool) {
stream = _stream;
- return StreamUtilities._processCancelation(_aceContractAddress, _proof2, _proof1OutputNotes, stream);
+ bool cancellationSuccess =
+ StreamUtilities._processCancellation(
+ _aceContractAddress,
+ _proof2,
+ _proof1OutputNotes,
+ stream
+ );
+ emit ProcessCancellation(cancellationSuccess);
}
}
diff --git a/packages/contracts/contracts/test/Imports.sol b/packages/contracts/contracts/test/Imports.sol
deleted file mode 100644
index 34f5978..0000000
--- a/packages/contracts/contracts/test/Imports.sol
+++ /dev/null
@@ -1,22 +0,0 @@
-pragma solidity ^0.5.11;
-
-import "@aztec/protocol/contracts/ACE/noteRegistry/epochs/201912/base/FactoryBase201912.sol";
-import "@aztec/protocol/contracts/ACE/ACE.sol";
-import "@aztec/protocol/contracts/ACE/validators/joinSplit/JoinSplit.sol";
-import "@aztec/protocol/contracts/ACE/validators/dividend/Dividend.sol";
-
-// You might think this file is a bit odd, but let me explain.
-// We only use some contracts in our tests, which means Truffle
-// will not compile it for us, because it is from an external
-// dependency.
-//
-// We are now left with three options:
-// - Copy/paste these contracts
-// - Run the tests with `truffle compile --all` on
-// - Or trick Truffle by claiming we use it in a Solidity test
-//
-// You know which one I went for.
-
-contract Imports {
- constructor() public {}
-}
diff --git a/packages/contracts/package.json b/packages/contracts/package.json
index 2bea997..93088e8 100644
--- a/packages/contracts/package.json
+++ b/packages/contracts/package.json
@@ -33,6 +33,7 @@
"@aztec/contract-artifacts": "^1.22.0",
"@aztec/dev-utils": "^2.3.1",
"@aztec/protocol": "^1.7.0",
+ "@aztec/secp256k1": "^1.2.0",
"@nomiclabs/buidler": "^1.3.3",
"@nomiclabs/buidler-ethers": "^1.3.3",
"@nomiclabs/buidler-etherscan": "^1.3.3",
@@ -40,6 +41,7 @@
"@notestream/dev-utils": "^0.1.0",
"@openzeppelin/contracts": "^2.5.0",
"@openzeppelin/upgrades": "^2.8.0",
+ "aztec.js": "^0.18.0",
"chai": "^4.2.0",
"chalk": "^4.0.0",
"crypto": "^1.0.1",
diff --git a/packages/contracts/test/NoteStream/cancelStream.js b/packages/contracts/test/NoteStream/cancelStream.js
index c49d70e..43c705e 100644
--- a/packages/contracts/test/NoteStream/cancelStream.js
+++ b/packages/contracts/test/NoteStream/cancelStream.js
@@ -9,6 +9,9 @@ const crypto = require('crypto');
const NoteStream = require('../../build/NoteStream.json');
const { noteStreamFixture } = require('../fixtures');
+const { mintZkAsset } = require('../helpers/mint/mintZkAssets');
+const { signProof } = require('../helpers/signProof');
+const { createStreamDepositProof } = require('../helpers/deposit/streamNote');
const {
contextForStreamDidEnd,
@@ -63,7 +66,6 @@ function testValidCancellation() {
// ).to.be.revertedWith('stream does not exist');
// }
);
- it('returns true');
}
function runTests() {
@@ -132,29 +134,56 @@ function runTests() {
}
describe('NoteStream - cancelStream', function () {
+ let ace;
+ let token;
let noteStream;
let zkAsset;
beforeEach(async function () {
- ({ noteStream, zkAsset } = await loadFixture(noteStreamFixture));
+ ({ ace, token, noteStream, zkAsset } = await loadFixture(
+ noteStreamFixture
+ ));
});
- const now = bigNumberify(moment().format('X'));
-
describe('when the stream exists', function () {
let streamId;
+ const streamDeposit = 100000;
beforeEach(async function () {
- const startTime = now.add(
- STANDARD_TIME_OFFSET.multipliedBy(2).toString()
+ const depositOutputNote = await mintZkAsset(
+ sender.address,
+ streamDeposit,
+ token,
+ zkAsset,
+ ace
);
+
+ const { depositProof } = await createStreamDepositProof(
+ [depositOutputNote],
+ noteStream.address,
+ sender.address,
+ recipient.address,
+ 0
+ );
+
+ const { data, signature } = signProof(
+ zkAsset,
+ depositProof,
+ noteStream.address,
+ sender.signingKey.privateKey
+ );
+
+ const now = bigNumberify(moment().format('X'));
+ const startTime = now.add(STANDARD_TIME_OFFSET.toString());
const stopTime = startTime.add(STANDARD_TIME_DELTA.toString());
- const notehash = crypto.randomBytes(32);
+
const tx = await noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
);
+
const receipt = await tx.wait();
streamId = NoteStreamInterface.parseLog(
receipt.logs[receipt.logs.length - 1]
diff --git a/packages/contracts/test/NoteStream/createStream.js b/packages/contracts/test/NoteStream/createStream.js
index ff5a11d..19885a1 100644
--- a/packages/contracts/test/NoteStream/createStream.js
+++ b/packages/contracts/test/NoteStream/createStream.js
@@ -3,10 +3,8 @@ const { waffle } = require('@nomiclabs/buidler');
const { use, expect } = require('chai');
const { solidity, createFixtureLoader } = require('ethereum-waffle');
const { bigNumberify, Interface } = require('ethers/utils');
-
const { devConstants } = require('@notestream/dev-utils');
const moment = require('moment');
-const crypto = require('crypto');
const {
// STANDARD_SALARY,
@@ -17,6 +15,9 @@ const {
const NoteStream = require('../../build/NoteStream.json');
const { noteStreamFixture } = require('../fixtures');
+const { mintZkAsset } = require('../helpers/mint/mintZkAssets');
+const { signProof } = require('../helpers/signProof');
+const { createStreamDepositProof } = require('../helpers/deposit/streamNote');
use(solidity);
@@ -27,23 +28,56 @@ describe('NoteStream - createStream', function () {
const NoteStreamInterface = new Interface(NoteStream.abi);
+ let ace;
+ let token;
let noteStream;
let zkAsset;
+ let streamNote;
+ let data;
+ let signature;
+ const streamDeposit = 100000;
beforeEach(async function () {
- ({ noteStream, zkAsset } = await loadFixture(noteStreamFixture));
+ ({ ace, token, noteStream, zkAsset } = await loadFixture(
+ noteStreamFixture
+ ));
+
+ const depositOutputNote = await mintZkAsset(
+ sender.address,
+ streamDeposit,
+ token,
+ zkAsset,
+ ace
+ );
+
+ const { depositProof } = await createStreamDepositProof(
+ [depositOutputNote],
+ noteStream.address,
+ sender.address,
+ recipient.address,
+ 0
+ );
+
+ [streamNote] = depositProof.outputNotes;
+
+ ({ data, signature } = signProof(
+ zkAsset,
+ depositProof,
+ noteStream.address,
+ sender.signingKey.privateKey
+ ));
});
const now = bigNumberify(moment().format('X'));
const startTime = now.add(STANDARD_TIME_OFFSET.toString());
const stopTime = startTime.add(STANDARD_TIME_DELTA.toString());
- const notehash = crypto.randomBytes(32);
describe('when not paused', function () {
describe('when the recipient is valid', function () {
it('creates the stream', async function () {
const tx = await noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
@@ -56,9 +90,7 @@ describe('NoteStream - createStream', function () {
const streamObject = await noteStream.getStream(streamId);
expect(streamObject.sender).to.equal(sender.address);
expect(streamObject.recipient).to.equal(recipient.address);
- expect(streamObject.noteHash).to.equal(
- `0x${notehash.toString('hex')}`
- );
+ expect(streamObject.noteHash).to.equal(streamNote.noteHash);
expect(streamObject.tokenAddress).to.equal(zkAsset.address);
expect(streamObject.startTime).to.equal(startTime);
@@ -70,7 +102,8 @@ describe('NoteStream - createStream', function () {
const currentStreamId = await noteStream.nextStreamId();
await noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
@@ -84,7 +117,8 @@ describe('NoteStream - createStream', function () {
await expect(
noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
@@ -99,7 +133,8 @@ describe('NoteStream - createStream', function () {
await expect(
noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
invalidStartTime,
stopTime
@@ -111,7 +146,8 @@ describe('NoteStream - createStream', function () {
await expect(
noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
startTime
@@ -126,7 +162,8 @@ describe('NoteStream - createStream', function () {
await expect(
noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
invalidStopTime
@@ -139,7 +176,8 @@ describe('NoteStream - createStream', function () {
await expect(
noteStream.createStream(
sender.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
@@ -151,7 +189,8 @@ describe('NoteStream - createStream', function () {
await expect(
noteStream.createStream(
noteStream.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
@@ -163,7 +202,8 @@ describe('NoteStream - createStream', function () {
await expect(
noteStream.createStream(
ZERO_ADDRESS,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
@@ -179,7 +219,8 @@ describe('NoteStream - createStream', function () {
await expect(
noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
diff --git a/packages/contracts/test/NoteStream/withdrawFromStream.js b/packages/contracts/test/NoteStream/withdrawFromStream.js
index 797d7dd..a34c1c1 100644
--- a/packages/contracts/test/NoteStream/withdrawFromStream.js
+++ b/packages/contracts/test/NoteStream/withdrawFromStream.js
@@ -1,10 +1,6 @@
const { waffle } = require('@nomiclabs/buidler');
const { use, expect } = require('chai');
-const {
- solidity,
- MockProvider,
- createFixtureLoader,
-} = require('ethereum-waffle');
+const { solidity, createFixtureLoader } = require('ethereum-waffle');
const { bigNumberify, Interface } = require('ethers/utils');
const { devConstants, mochaContexts } = require('@notestream/dev-utils');
@@ -13,6 +9,9 @@ const crypto = require('crypto');
const NoteStream = require('../../build/NoteStream.json');
const { noteStreamFixture } = require('../fixtures');
+const { mintZkAsset } = require('../helpers/mint/mintZkAssets');
+const { signProof } = require('../helpers/signProof');
+const { createStreamDepositProof } = require('../helpers/deposit/streamNote');
const {
contextForStreamDidEnd,
@@ -29,144 +28,63 @@ const {
use(solidity);
-function runTests() {
- const { provider } = waffle;
- const [sender, recipient] = provider.getWallets();
- const loadFixture = createFixtureLoader(provider, [sender, recipient]);
-
- const NoteStreamInterface = new Interface(NoteStream.abi);
-
- let noteStream;
- let zkAsset;
- let streamId;
- beforeEach(async function () {
- ({ noteStream, zkAsset } = await loadFixture(noteStreamFixture));
- const now = bigNumberify(moment().format('X'));
- const startTime = now.add(STANDARD_TIME_OFFSET.toString());
- const stopTime = startTime.add(STANDARD_TIME_DELTA.toString());
-
- const notehash = crypto.randomBytes(32);
- const tx = await noteStream.createStream(
- recipient.address,
- notehash,
- zkAsset.address,
- startTime,
- stopTime
- );
- const receipt = await tx.wait();
- streamId = NoteStreamInterface.parseLog(
- receipt.logs[receipt.logs.length - 1]
- ).values.streamId;
- noteStream = noteStream.connect(recipient);
- });
-
- describe('when the withdrawal amount is higher than 0', function () {
- it('reverts if the stream did not start', async function () {
- const dividendProof = crypto.randomBytes(1);
- const joinSplitProof = crypto.randomBytes(1);
- const withrawDuration = FIVE_UNITS.toString(10);
- await expect(
- noteStream.withdrawFromStream(
- streamId,
- dividendProof,
- joinSplitProof,
- withrawDuration
- )
- ).to.be.revertedWith('withdraw is greater than allowed');
- });
-
- contextForStreamDidStartButNotEnd(provider, function () {
- it('reverts if the withdrawal amount exceeds the available balance', async function () {
- const withdrawDuration = STANDARD_TIME_OFFSET.multipliedBy(
- 2
- ).toString(10);
- const dividendProof = crypto.randomBytes(1);
- const joinSplitProof = crypto.randomBytes(1);
- await expect(
- noteStream.withdrawFromStream(
- streamId,
- dividendProof,
- joinSplitProof,
- withdrawDuration
- )
- ).to.be.revertedWith('withdraw is greater than allowed');
- });
- it('updates the streams lastWithdrawTime parameter');
- it('emits a WithdrawFromStream event');
- });
-
- contextForStreamDidEnd(provider, function () {
- it('reverts if the withdrawal amount exceeds the available balance', async function () {
- const withdrawDuration = bigNumberify(
- STANDARD_TIME_DELTA.toString()
- )
- .mul(2)
- .toString();
- const dividendProof = crypto.randomBytes(1);
- const joinSplitProof = crypto.randomBytes(1);
- await expect(
- noteStream.withdrawFromStream(
- streamId,
- dividendProof,
- joinSplitProof,
- withdrawDuration
- )
- ).to.be.revertedWith('withdraw is greater than allowed');
- });
- describe('when the balance is not withdrawn in full', function () {
- it('updates the streams lastWithdrawTime parameter');
- it('emits a WithdrawFromStream event');
- });
- describe('when the balance is withdrawn in full', function () {
- it('updates the streams lastWithdrawTime parameter');
- it('emits a WithdrawFromStream event');
- });
- });
- });
-
- it('reverts when the withdrawal amount is zero', async function () {
- const dividendProof = crypto.randomBytes(1);
- const joinSplitProof = crypto.randomBytes(1);
- const withdrawalDuration = '0';
- await expect(
- noteStream.withdrawFromStream(
- streamId,
- dividendProof,
- joinSplitProof,
- withdrawalDuration
- )
- ).to.be.revertedWith('zero value withdrawal');
- });
-}
-
describe('NoteStream - withdrawFromStream', function () {
- const provider = new MockProvider();
- const [sender, recipient] = provider.getWallets();
+ const { provider } = waffle;
+ const [sender, recipient, attacker] = provider.getWallets();
const loadFixture = createFixtureLoader(provider, [sender, recipient]);
const NoteStreamInterface = new Interface(NoteStream.abi);
+ let ace;
+ let token;
let noteStream;
let zkAsset;
beforeEach(async function () {
- ({ noteStream, zkAsset } = await loadFixture(noteStreamFixture));
+ ({ ace, token, noteStream, zkAsset } = await loadFixture(
+ noteStreamFixture
+ ));
});
describe('when the stream exists', function () {
let streamId;
+ const streamDeposit = 100000;
beforeEach(async function () {
+ const depositOutputNote = await mintZkAsset(
+ sender.address,
+ streamDeposit,
+ token,
+ zkAsset,
+ ace
+ );
+
+ const { depositProof } = await createStreamDepositProof(
+ [depositOutputNote],
+ noteStream.address,
+ sender.address,
+ recipient.address,
+ 0
+ );
+
+ const { data, signature } = signProof(
+ zkAsset,
+ depositProof,
+ noteStream.address,
+ sender.signingKey.privateKey
+ );
+
const now = bigNumberify(moment().format('X'));
const startTime = now.add(STANDARD_TIME_OFFSET.toString());
const stopTime = startTime.add(STANDARD_TIME_DELTA.toString());
- const notehash = crypto.randomBytes(32);
const tx = await noteStream.createStream(
recipient.address,
- notehash,
+ data,
+ signature,
zkAsset.address,
startTime,
stopTime
);
+
const receipt = await tx.wait();
streamId = NoteStreamInterface.parseLog(
receipt.logs[receipt.logs.length - 1]
@@ -178,17 +96,105 @@ describe('NoteStream - withdrawFromStream', function () {
const joinSplitProof = crypto.randomBytes(1);
const withdrawDuration = 1;
await expect(
- noteStream.withdrawFromStream(
- streamId,
- dividendProof,
- joinSplitProof,
- withdrawDuration
- )
+ noteStream
+ .connect(sender)
+ .withdrawFromStream(
+ streamId,
+ dividendProof,
+ joinSplitProof,
+ withdrawDuration
+ )
).to.be.revertedWith('caller is not the recipient of the stream');
});
describe('when the caller is the recipient of the stream', function () {
- runTests();
+ beforeEach(function () {
+ noteStream = noteStream.connect(recipient);
+ });
+
+ describe('when the withdrawal amount is higher than 0', function () {
+ it('reverts if the stream did not start', async function () {
+ const dividendProof = crypto.randomBytes(1);
+ const joinSplitProof = crypto.randomBytes(1);
+ const withrawDuration = FIVE_UNITS.toString(10);
+ await expect(
+ noteStream.withdrawFromStream(
+ streamId,
+ dividendProof,
+ joinSplitProof,
+ withrawDuration
+ )
+ ).to.be.revertedWith('withdraw is greater than allowed');
+ });
+
+ contextForStreamDidStartButNotEnd(provider, function () {
+ it('reverts if the withdrawal amount exceeds the available balance', async function () {
+ const withdrawDuration = STANDARD_TIME_OFFSET.multipliedBy(
+ 2
+ ).toString(10);
+ const dividendProof = crypto.randomBytes(1);
+ const joinSplitProof = crypto.randomBytes(1);
+ await expect(
+ noteStream.withdrawFromStream(
+ streamId,
+ dividendProof,
+ joinSplitProof,
+ withdrawDuration
+ )
+ ).to.be.revertedWith(
+ 'withdraw is greater than allowed'
+ );
+ });
+ it('updates the streams lastWithdrawTime parameter');
+ it('emits a WithdrawFromStream event');
+ });
+
+ contextForStreamDidEnd(provider, function () {
+ it('reverts if the withdrawal amount exceeds the available balance', async function () {
+ const withdrawDuration = bigNumberify(
+ STANDARD_TIME_DELTA.toString()
+ )
+ .mul(2)
+ .toString();
+ const dividendProof = crypto.randomBytes(1);
+ const joinSplitProof = crypto.randomBytes(1);
+ await expect(
+ noteStream.withdrawFromStream(
+ streamId,
+ dividendProof,
+ joinSplitProof,
+ withdrawDuration
+ )
+ ).to.be.revertedWith(
+ 'withdraw is greater than allowed'
+ );
+ });
+ describe('when the balance is not withdrawn in full', function () {
+ it('updates the streams lastWithdrawTime parameter');
+ it('emits a WithdrawFromStream event');
+ });
+ describe('when the balance is withdrawn in full', function () {
+ it('updates the streams lastWithdrawTime parameter');
+ it('emits a WithdrawFromStream event');
+ });
+ });
+ });
+
+ it('reverts when the withdrawal amount is zero', async function () {
+ const dividendProof = crypto.randomBytes(1);
+ const joinSplitProof = crypto.randomBytes(1);
+ const withdrawalDuration = '0';
+ await expect(
+ noteStream
+ .connect(recipient)
+ .withdrawFromStream(
+ streamId,
+ dividendProof,
+ joinSplitProof,
+ withdrawalDuration
+ )
+ ).to.be.revertedWith('zero value withdrawal');
+ });
});
it('reverts when the caller is not the sender or the recipient of the stream', async function () {
@@ -196,12 +202,14 @@ describe('NoteStream - withdrawFromStream', function () {
const joinSplitProof = crypto.randomBytes(1);
const withdrawDuration = 1;
await expect(
- noteStream.withdrawFromStream(
- streamId,
- dividendProof,
- joinSplitProof,
- withdrawDuration
- )
+ noteStream
+ .connect(attacker)
+ .withdrawFromStream(
+ streamId,
+ dividendProof,
+ joinSplitProof,
+ withdrawDuration
+ )
).to.be.revertedWith('caller is not the recipient of the stream');
});
});
@@ -210,12 +218,12 @@ describe('NoteStream - withdrawFromStream', function () {
const dividendProof = crypto.randomBytes(1);
const joinSplitProof = crypto.randomBytes(1);
const withdrawDuration = 1;
- const streamId = bigNumberify(419863);
+ const badStreamId = bigNumberify(419863);
await expect(
noteStream
.connect(recipient)
.withdrawFromStream(
- streamId,
+ badStreamId,
dividendProof,
joinSplitProof,
withdrawDuration
diff --git a/packages/contracts/test/StreamUtilities/getRatio.js b/packages/contracts/test/StreamUtilities/getRatio.js
index b96fe77..1b763f3 100644
--- a/packages/contracts/test/StreamUtilities/getRatio.js
+++ b/packages/contracts/test/StreamUtilities/getRatio.js
@@ -1,8 +1,11 @@
const { waffle } = require('@nomiclabs/buidler');
-const { use } = require('chai');
+const { use, expect } = require('chai');
const { solidity, createFixtureLoader } = require('ethereum-waffle');
+const { DividendProof } = require('aztec.js');
const { StreamUtilitiesFixture } = require('../fixtures');
+const { createNote } = require('../helpers/notes/createNote');
+
use(solidity);
describe('StreamUtilities - getRatio', function () {
@@ -16,5 +19,51 @@ describe('StreamUtilities - getRatio', function () {
({ streamUtilitiesMock } = await loadFixture(StreamUtilitiesFixture));
});
- it('returns the correct ratio');
+ it('returns the correct ratio', async function () {
+ // 1 * 1000 = 3 * 333 + 1
+ const inputNoteValue = 1000;
+ const withdrawNoteValue = 333;
+ const remainderNoteValue = 1;
+ const ratioNumerator = 1;
+ const ratioDenominator = 3;
+
+ // This is defined on the contract
+ const scalingFactor = 1000000000;
+
+ const inputNote = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const withdrawNote = await createNote(
+ withdrawNoteValue,
+ sender.address,
+ [sender.address]
+ );
+
+ const remainderNote = await createNote(
+ remainderNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const badProofData = new DividendProof(
+ inputNote,
+ remainderNote,
+ withdrawNote,
+ streamUtilitiesMock.address,
+ ratioDenominator,
+ ratioNumerator
+ ).encodeABI();
+
+ const ratio = await streamUtilitiesMock.getRatio(badProofData);
+
+ // We flip the ratio as we require an integer value
+ const expectedRatio = parseInt(
+ (ratioDenominator * scalingFactor) / ratioNumerator,
+ 10
+ );
+ expect(ratio).to.be.equal(expectedRatio);
+ });
});
diff --git a/packages/contracts/test/StreamUtilities/index.js b/packages/contracts/test/StreamUtilities/index.js
index b904d14..d1e55e8 100644
--- a/packages/contracts/test/StreamUtilities/index.js
+++ b/packages/contracts/test/StreamUtilities/index.js
@@ -1,4 +1,5 @@
require('./getRatio.js');
+require('./processDeposit.js');
require('./validateRatioProof.js');
require('./validateJoinSplitProof.js');
require('./processWithdrawal.js');
diff --git a/packages/contracts/test/StreamUtilities/processCancellation.js b/packages/contracts/test/StreamUtilities/processCancellation.js
index 7a10bf2..c683617 100644
--- a/packages/contracts/test/StreamUtilities/processCancellation.js
+++ b/packages/contracts/test/StreamUtilities/processCancellation.js
@@ -1,7 +1,11 @@
const { waffle } = require('@nomiclabs/buidler');
-const { use } = require('chai');
+const { use, expect } = require('chai');
const { solidity, createFixtureLoader } = require('ethereum-waffle');
+const { JoinSplitProof } = require('aztec.js');
+
const { StreamUtilitiesFixture } = require('../fixtures');
+const { createNote } = require('../helpers/notes/createNote');
+const { mintZkAsset } = require('../helpers/mint/mintZkAssets');
use(solidity);
@@ -10,16 +14,186 @@ describe('StreamUtilities - processCancellation', function () {
const [sender, recipient] = provider.getWallets();
const loadFixture = createFixtureLoader(provider, [sender, recipient]);
- // eslint-disable-next-line no-unused-vars
+ let ace;
+ let token;
+ let zkAsset;
+ let streamNote;
let streamUtilitiesMock;
+ let streamObject;
+ const streamDeposit = 100000;
beforeEach(async function () {
- ({ streamUtilitiesMock } = await loadFixture(StreamUtilitiesFixture));
+ ({ ace, streamUtilitiesMock, token, zkAsset } = await loadFixture(
+ StreamUtilitiesFixture
+ ));
+
+ streamNote = await mintZkAsset(
+ streamUtilitiesMock.address,
+ streamDeposit,
+ token,
+ zkAsset,
+ ace
+ );
+
+ streamObject = {
+ noteHash: streamNote.noteHash,
+ startTime: 0,
+ lastWithdrawTime: 50,
+ stopTime: 100,
+ recipient: recipient.address,
+ sender: sender.address,
+ tokenAddress: zkAsset.address,
+ isEntity: true,
+ };
+ });
+
+ const runTest = async (
+ withdrawNoteOwner,
+ withdrawNoteViewAccess,
+ refundNoteOwner,
+ refundNoteViewAccess,
+ error
+ ) => {
+ const withdrawalNote = await createNote(
+ streamNote.k.toNumber() / 4,
+ withdrawNoteOwner,
+ [withdrawNoteViewAccess]
+ );
+
+ const refundNote = await createNote(
+ (streamNote.k.toNumber() * 3) / 4,
+ refundNoteOwner,
+ [refundNoteViewAccess]
+ );
+
+ const badProof = new JoinSplitProof(
+ [streamNote],
+ [withdrawalNote, refundNote],
+ streamUtilitiesMock.address,
+ 0,
+ withdrawNoteOwner
+ );
+
+ const badProofData = badProof.encodeABI(zkAsset.address);
+
+ await expect(
+ streamUtilitiesMock.processCancellation(
+ ace.address,
+ badProofData,
+ withdrawalNote.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith(error);
+ };
+
+ it('reverts if withdraw note is not owned by recipient', async function () {
+ await runTest(
+ sender.address, // incorrect
+ recipient.address,
+ sender.address,
+ sender.address,
+ "Stream recipient doesn't own first output note"
+ );
+ });
+
+ it('reverts if refund note is not owned by sender', async function () {
+ await runTest(
+ recipient.address,
+ recipient.address,
+ recipient.address, // incorrect
+ sender.address,
+ "Stream sender doesn't own second output note"
+ );
+ });
+
+ it('reverts if recipient does not have view access to the withdraw note', async function () {
+ await runTest(
+ recipient.address,
+ sender.address, // incorrect
+ sender.address,
+ sender.address,
+ "stream recipient can't view withdrawal note"
+ );
});
- it('reverts if withdraw note is not owned by recipient');
- it('reverts if refund note is not owned by sender');
- it('reverts if recipient does not have view access to the withdraw note');
- it('reverts if sender does not have view access to the refund note');
- it('emits a confidentialTransfer event');
- it('returns true');
+ it('reverts if sender does not have view access to the refund note', async function () {
+ await runTest(
+ recipient.address,
+ recipient.address,
+ sender.address,
+ recipient.address, // incorrect
+ "stream sender can't view refund note"
+ );
+ });
+
+ it('transfers the zkAssets to the sender and recipient', async function () {
+ const withdrawalNote = await createNote(
+ streamNote.k.toNumber() / 4,
+ recipient.address,
+ [recipient.address]
+ );
+
+ const refundNote = await createNote(
+ (streamNote.k.toNumber() * 3) / 4,
+ sender.address,
+ [sender.address]
+ );
+
+ const proof = new JoinSplitProof(
+ [streamNote],
+ [withdrawalNote, refundNote],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ );
+
+ const proofData = proof.encodeABI(zkAsset.address);
+
+ await expect(
+ streamUtilitiesMock.processCancellation(
+ ace.address,
+ proofData,
+ withdrawalNote.noteHash,
+ streamObject
+ )
+ )
+ .to.emit(zkAsset, 'DestroyNote')
+ .withArgs(streamUtilitiesMock.address, streamNote.noteHash);
+ });
+
+ it('transfers the zkAssets to the sender and recipient and returns true', async function () {
+ const withdrawalNote = await createNote(
+ streamNote.k.toNumber() / 4,
+ recipient.address,
+ [recipient.address]
+ );
+
+ const refundNote = await createNote(
+ (streamNote.k.toNumber() * 3) / 4,
+ sender.address,
+ [sender.address]
+ );
+
+ const proof = new JoinSplitProof(
+ [streamNote],
+ [withdrawalNote, refundNote],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ );
+
+ const proofData = proof.encodeABI(zkAsset.address);
+
+ await expect(
+ streamUtilitiesMock.processCancellation(
+ ace.address,
+ proofData,
+ withdrawalNote.noteHash,
+ streamObject
+ )
+ )
+ .to.emit(zkAsset, 'DestroyNote')
+ .withArgs(streamUtilitiesMock.address, streamNote.noteHash)
+ .and.emit(streamUtilitiesMock, 'ProcessCancellation')
+ .withArgs(true);
+ });
});
diff --git a/packages/contracts/test/StreamUtilities/processDeposit.js b/packages/contracts/test/StreamUtilities/processDeposit.js
new file mode 100644
index 0000000..08b24c5
--- /dev/null
+++ b/packages/contracts/test/StreamUtilities/processDeposit.js
@@ -0,0 +1,242 @@
+const { waffle } = require('@nomiclabs/buidler');
+const { use, expect } = require('chai');
+const { solidity, createFixtureLoader } = require('ethereum-waffle');
+const { JoinSplitProof } = require('aztec.js');
+
+const { StreamUtilitiesFixture } = require('../fixtures');
+const { mintZkAsset } = require('../helpers/mint/mintZkAssets');
+const { createNote } = require('../helpers/notes/createNote');
+const {
+ getStreamNote,
+ createStreamDepositProof,
+} = require('../helpers/deposit/streamNote');
+const { signProof } = require('../helpers/signProof');
+
+use(solidity);
+
+describe('StreamUtilities - processDeposit', function () {
+ const { provider } = waffle;
+ const [sender, recipient] = provider.getWallets();
+ const loadFixture = createFixtureLoader(provider, [sender, recipient]);
+
+ let ace;
+ let token;
+ let zkAsset;
+ let depositOutputNote;
+ let streamUtilitiesMock;
+ const streamDeposit = 100000;
+ beforeEach(async function () {
+ ({
+ ace,
+ streamUtilitiesMock,
+ token,
+ zkAsset,
+ // depositOutputNotes,
+ } = await loadFixture(StreamUtilitiesFixture));
+
+ depositOutputNote = await mintZkAsset(
+ sender.address,
+ streamDeposit,
+ token,
+ zkAsset,
+ ace
+ );
+ });
+
+ it('reverts if there is no output note', async function () {
+ const badProof = new JoinSplitProof(
+ [depositOutputNote],
+ [],
+ sender.address,
+ streamDeposit,
+ sender.address
+ );
+ const { data, signature } = signProof(
+ zkAsset,
+ badProof,
+ streamUtilitiesMock.address,
+ sender.signingKey.privateKey
+ );
+
+ await expect(
+ streamUtilitiesMock.processDeposit(
+ data,
+ signature,
+ ace.address,
+ sender.address,
+ recipient.address,
+ zkAsset.address
+ )
+ ).to.be.revertedWith('Incorrect number of output notes');
+ });
+ it('reverts if there is more than one output note', async function () {
+ const note1 = await getStreamNote(
+ streamDeposit / 2,
+ streamUtilitiesMock.address,
+ sender.address,
+ recipient.address
+ );
+ const note2 = await getStreamNote(
+ streamDeposit / 2,
+ streamUtilitiesMock.address,
+ sender.address,
+ recipient.address
+ );
+
+ const badProof = new JoinSplitProof(
+ [depositOutputNote],
+ [note1, note2],
+ sender.address,
+ 0,
+ sender.address
+ );
+
+ const { data, signature } = signProof(
+ zkAsset,
+ badProof,
+ streamUtilitiesMock.address,
+ sender.signingKey.privateKey
+ );
+
+ await expect(
+ streamUtilitiesMock.processDeposit(
+ data,
+ signature,
+ ace.address,
+ sender.address,
+ recipient.address,
+ zkAsset.address
+ )
+ ).to.be.revertedWith('Incorrect number of output notes');
+ });
+ it('reverts if streamNote is not owned by the contract', async function () {
+ const badNote = await getStreamNote(
+ streamDeposit,
+ sender.address,
+ sender.address,
+ recipient.address
+ );
+
+ const badProof = new JoinSplitProof(
+ [depositOutputNote],
+ [badNote],
+ sender.address,
+ 0,
+ sender.address
+ );
+
+ const { data, signature } = signProof(
+ zkAsset,
+ badProof,
+ streamUtilitiesMock.address,
+ sender.signingKey.privateKey
+ );
+
+ await expect(
+ streamUtilitiesMock.processDeposit(
+ data,
+ signature,
+ ace.address,
+ sender.address,
+ recipient.address,
+ zkAsset.address
+ )
+ ).to.be.revertedWith('stream note is not owned by stream contract');
+ });
+ it('reverts if sender does not have view access to the streamNote', async function () {
+ const badNote = await createNote(
+ streamDeposit,
+ streamUtilitiesMock.address,
+ [recipient.address]
+ );
+
+ const badProof = new JoinSplitProof(
+ [depositOutputNote],
+ [badNote],
+ sender.address,
+ 0,
+ sender.address
+ );
+
+ const { data, signature } = signProof(
+ zkAsset,
+ badProof,
+ streamUtilitiesMock.address,
+ sender.signingKey.privateKey
+ );
+
+ await expect(
+ streamUtilitiesMock.processDeposit(
+ data,
+ signature,
+ ace.address,
+ sender.address,
+ recipient.address,
+ zkAsset.address
+ )
+ ).to.be.revertedWith("stream sender can't view stream note");
+ });
+ it('reverts if recipient does not have view access to the streamNote', async function () {
+ const badNote = await createNote(
+ streamDeposit,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const badProof = new JoinSplitProof(
+ [depositOutputNote],
+ [badNote],
+ sender.address,
+ 0,
+ sender.address
+ );
+
+ const { data, signature } = signProof(
+ zkAsset,
+ badProof,
+ streamUtilitiesMock.address,
+ sender.signingKey.privateKey
+ );
+
+ await expect(
+ streamUtilitiesMock.processDeposit(
+ data,
+ signature,
+ ace.address,
+ sender.address,
+ recipient.address,
+ zkAsset.address
+ )
+ ).to.be.revertedWith("stream recipient can't view stream note");
+ });
+ it('transfers the zkAssets to the contract and returns the new stream note hash', async function () {
+ const { depositProof, streamNote } = await createStreamDepositProof(
+ [depositOutputNote],
+ streamUtilitiesMock.address,
+ sender.address,
+ recipient.address,
+ 0
+ );
+
+ const { data, signature } = signProof(
+ zkAsset,
+ depositProof,
+ streamUtilitiesMock.address,
+ sender.signingKey.privateKey
+ );
+ await expect(
+ streamUtilitiesMock.processDeposit(
+ data,
+ signature,
+ ace.address,
+ sender.address,
+ recipient.address,
+ zkAsset.address
+ )
+ )
+ .to.emit(zkAsset, 'DestroyNote')
+ .withArgs(sender.address, depositOutputNote.noteHash)
+ .and.emit(streamUtilitiesMock, 'ProcessDeposit')
+ .withArgs(streamNote.noteHash);
+ });
+});
diff --git a/packages/contracts/test/StreamUtilities/processWithdrawal.js b/packages/contracts/test/StreamUtilities/processWithdrawal.js
index 7d4cdbc..5caedf4 100644
--- a/packages/contracts/test/StreamUtilities/processWithdrawal.js
+++ b/packages/contracts/test/StreamUtilities/processWithdrawal.js
@@ -1,7 +1,11 @@
const { waffle } = require('@nomiclabs/buidler');
-const { use } = require('chai');
+const { use, expect } = require('chai');
const { solidity, createFixtureLoader } = require('ethereum-waffle');
+const { JoinSplitProof } = require('aztec.js');
+
const { StreamUtilitiesFixture } = require('../fixtures');
+const { mintZkAsset } = require('../helpers/mint/mintZkAssets');
+const { createNote } = require('../helpers/notes/createNote');
use(solidity);
@@ -10,16 +14,213 @@ describe('StreamUtilities - processWithdrawal', function () {
const [sender, recipient] = provider.getWallets();
const loadFixture = createFixtureLoader(provider, [sender, recipient]);
- // eslint-disable-next-line no-unused-vars
+ let ace;
+ let token;
+ let zkAsset;
+ let streamNote;
let streamUtilitiesMock;
+ let streamObject;
+ const streamDeposit = 100000;
beforeEach(async function () {
- ({ streamUtilitiesMock } = await loadFixture(StreamUtilitiesFixture));
+ ({ ace, streamUtilitiesMock, token, zkAsset } = await loadFixture(
+ StreamUtilitiesFixture
+ ));
+
+ streamNote = await mintZkAsset(
+ streamUtilitiesMock.address,
+ streamDeposit,
+ token,
+ zkAsset,
+ ace
+ );
+
+ streamObject = {
+ noteHash: streamNote.noteHash,
+ startTime: 0,
+ lastWithdrawTime: 50,
+ stopTime: 100,
+ recipient: recipient.address,
+ sender: sender.address,
+ tokenAddress: zkAsset.address,
+ isEntity: true,
+ };
+ });
+
+ it('reverts if new streamNote is not owned by NoteStream contract', async function () {
+ const withdrawalNote = await createNote(
+ streamNote.k.toNumber() / 4,
+ recipient.address,
+ [recipient.address]
+ );
+
+ // Try to steal refund note by setting sender as owner
+ const refundNote = await createNote(
+ (streamNote.k.toNumber() * 3) / 4,
+ sender.address,
+ [sender.address, recipient.address]
+ );
+
+ const badProof = new JoinSplitProof(
+ [streamNote],
+ [withdrawalNote, refundNote],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ );
+ const badProofData = badProof.encodeABI(zkAsset.address);
+
+ await expect(
+ streamUtilitiesMock.processWithdrawal(
+ ace.address,
+ badProofData,
+ withdrawalNote.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith(
+ 'change note in 2 is not owned by stream contract'
+ );
+ });
+
+ // it('reverts if withdraw note is not owned by recipient', async function () {
+ // // Try to steal withdrawal note by setting sender as owner
+ // const badWithdrawalNote = await createNote(
+ // streamNote.k.toNumber() / 4,
+ // sender.address,
+ // [sender.address]
+ // );
+
+ // const refundNote = await createNote(
+ // (streamNote.k.toNumber() * 3) / 4,
+ // streamUtilitiesMock.address,
+ // [sender.address, recipient.address]
+ // );
+
+ // const badProof = new JoinSplitProof(
+ // [streamNote],
+ // [badWithdrawalNote, refundNote],
+ // streamUtilitiesMock.address,
+ // 0,
+ // sender.address
+ // );
+
+ // const badProofData = badProof.encodeABI(zkAsset.address);
+
+ // await expect(
+ // streamUtilitiesMock.processWithdrawal(
+ // ace.address,
+ // badProofData,
+ // badWithdrawalNote.noteHash,
+ // streamObject
+ // )
+ // ).to.be.revertedWith(
+ // 'change note in 2 is not owned by stream contract'
+ // );
+ // });
+
+ it('reverts if sender does not have view access to the new streamNote', async function () {
+ // withdraw 1/4th of note
+ const withdrawalNote = await createNote(
+ streamNote.k.toNumber() / 4,
+ recipient.address,
+ [recipient.address]
+ );
+
+ // Here the sender has not given themself view access to the note
+ const badRefundNote = await createNote(
+ (streamNote.k.toNumber() * 3) / 4,
+ streamUtilitiesMock.address,
+ [recipient.address]
+ );
+
+ const badProof = new JoinSplitProof(
+ [streamNote],
+ [withdrawalNote, badRefundNote],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ );
+
+ const badProofData = badProof.encodeABI(zkAsset.address);
+
+ await expect(
+ streamUtilitiesMock.processWithdrawal(
+ ace.address,
+ badProofData,
+ withdrawalNote.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith("stream sender can't view new stream note");
});
- it('reverts if new streamNote is not owned by NoteStream contract');
- it('reverts if withdraw note is not owned by recipient');
- it('reverts if sender does not have view access to the new streamNote');
- it('reverts if recipient does not have view access to the new streamNote');
- it('emits a confidentialTransfer event');
- it('returns the hash of the first output note');
+ it('reverts if recipient does not have view access to the new streamNote', async function () {
+ // withdraw 1/4th of note
+ const withdrawalNote = await createNote(
+ streamNote.k.toNumber() / 4,
+ recipient.address,
+ [recipient.address]
+ );
+
+ // Here the sender has not given the recipient view access to the note
+ const badRefundNote = await createNote(
+ (streamNote.k.toNumber() * 3) / 4,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const badProof = new JoinSplitProof(
+ [streamNote],
+ [withdrawalNote, badRefundNote],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ );
+
+ const badProofData = badProof.encodeABI(zkAsset.address);
+
+ await expect(
+ streamUtilitiesMock.processWithdrawal(
+ ace.address,
+ badProofData,
+ withdrawalNote.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith("stream recipient can't view new stream note");
+ });
+
+ it('transfers the zkAssets to the sender and recipient and returns the hash of the new stream note', async function () {
+ const withdrawalNote = await createNote(
+ streamNote.k.toNumber() / 4,
+ recipient.address,
+ [recipient.address]
+ );
+
+ const refundNote = await createNote(
+ (streamNote.k.toNumber() * 3) / 4,
+ streamUtilitiesMock.address,
+ [sender.address, recipient.address]
+ );
+
+ const proof = new JoinSplitProof(
+ [streamNote],
+ [withdrawalNote, refundNote],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ );
+
+ const proofData = proof.encodeABI(zkAsset.address);
+
+ await expect(
+ streamUtilitiesMock.processWithdrawal(
+ ace.address,
+ proofData,
+ withdrawalNote.noteHash,
+ streamObject
+ )
+ )
+ .to.emit(zkAsset, 'DestroyNote')
+ .withArgs(streamUtilitiesMock.address, streamNote.noteHash)
+ .and.emit(streamUtilitiesMock, 'ProcessWithdrawal')
+ .withArgs(refundNote.noteHash);
+ });
});
diff --git a/packages/contracts/test/StreamUtilities/validateJoinSplitProof.js b/packages/contracts/test/StreamUtilities/validateJoinSplitProof.js
index 18c671e..d5336a6 100644
--- a/packages/contracts/test/StreamUtilities/validateJoinSplitProof.js
+++ b/packages/contracts/test/StreamUtilities/validateJoinSplitProof.js
@@ -1,7 +1,9 @@
const { waffle } = require('@nomiclabs/buidler');
-const { use } = require('chai');
+const { use, expect } = require('chai');
const { solidity, createFixtureLoader } = require('ethereum-waffle');
+const { JoinSplitProof } = require('aztec.js');
const { StreamUtilitiesFixture } = require('../fixtures');
+const { createNote } = require('../helpers/notes/createNote');
use(solidity);
@@ -10,16 +12,240 @@ describe('StreamUtilities - validateJoinSplitProof', function () {
const [sender, recipient] = provider.getWallets();
const loadFixture = createFixtureLoader(provider, [sender, recipient]);
- // eslint-disable-next-line no-unused-vars
+ let ace;
let streamUtilitiesMock;
+ let zkAsset;
+ let streamObjectTemplate;
beforeEach(async function () {
- ({ streamUtilitiesMock } = await loadFixture(StreamUtilitiesFixture));
+ ({ ace, streamUtilitiesMock, zkAsset } = await loadFixture(
+ StreamUtilitiesFixture
+ ));
+ streamObjectTemplate = {
+ startTime: 0,
+ lastWithdrawTime: 50,
+ stopTime: 100,
+ recipient: recipient.address,
+ sender: sender.address,
+ tokenAddress: zkAsset.address,
+ isEntity: true,
+ };
+ });
+
+ it('reverts if proof has a non-zero public value transfer', async function () {
+ const inputNoteValue = 1000;
+ const outputNoteValue = 250;
+ const publicValue = 500;
+
+ const inputNote = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const outputNote1 = await createNote(outputNoteValue, sender.address, [
+ sender.address,
+ ]);
+
+ const outputNote2 = await createNote(
+ outputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const badProof = new JoinSplitProof(
+ [inputNote],
+ [outputNote1, outputNote2],
+ streamUtilitiesMock.address,
+ publicValue,
+ sender.address
+ );
+ const badProofData = badProof.encodeABI(zkAsset.address);
+
+ const streamObject = {
+ ...streamObjectTemplate,
+ noteHash: inputNote.noteHash,
+ };
+
+ await expect(
+ streamUtilitiesMock.validateJoinSplitProof(
+ ace.address,
+ badProofData,
+ outputNote1.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith('nonzero public value transfer');
+ });
+
+ it('reverts if proof does not have one input note only', async function () {
+ const inputNoteValue = 1000;
+
+ const inputNote1 = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const inputNote2 = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ // We only use one output note as we exect the function to revert before it's checked
+ const outputNote = await createNote(
+ 2 * inputNoteValue,
+ sender.address,
+ [sender.address]
+ );
+
+ const badProofData = new JoinSplitProof(
+ [inputNote1, inputNote2],
+ [outputNote],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ ).encodeABI(zkAsset.address);
+
+ const streamObject = {
+ ...streamObjectTemplate,
+ noteHash: inputNote1.noteHash,
+ };
+
+ await expect(
+ streamUtilitiesMock.validateJoinSplitProof(
+ ace.address,
+ badProofData,
+ outputNote.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith('Incorrect number of input notes');
+ });
+
+ it('reverts if proof does not have two output notes only', async function () {
+ const noteValue = 1000;
+
+ const inputNote = await createNote(
+ noteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const outputNote = await createNote(noteValue, sender.address, [
+ sender.address,
+ ]);
+
+ const badProofData = new JoinSplitProof(
+ [inputNote],
+ [outputNote],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ ).encodeABI(zkAsset.address);
+
+ const streamObject = {
+ ...streamObjectTemplate,
+ noteHash: inputNote.noteHash,
+ };
+
+ await expect(
+ streamUtilitiesMock.validateJoinSplitProof(
+ ace.address,
+ badProofData,
+ outputNote.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith('Incorrect number of output notes');
+ });
+
+ it('reverts if proof does not use same withdraw note as dividend proof', async function () {
+ const inputNoteValue = 1000;
+ const outputNoteValue = 500;
+
+ const inputNote = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const outputNote1 = await createNote(outputNoteValue, sender.address, [
+ sender.address,
+ ]);
+
+ const outputNote2 = await createNote(
+ outputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const badProofData = new JoinSplitProof(
+ [inputNote],
+ [outputNote1, outputNote2],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ ).encodeABI(zkAsset.address);
+
+ const streamObject = {
+ ...streamObjectTemplate,
+ noteHash: inputNote.noteHash,
+ };
+
+ // Here we pass the hash of outputNote2
+ // To be a valid proof we should have usedoutputNote1
+ await expect(
+ streamUtilitiesMock.validateJoinSplitProof(
+ ace.address,
+ badProofData,
+ outputNote2.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith('withdraw note in 2 is not the same as 1');
+ });
+
+ it('reverts if proof does not use stream note as input', async function () {
+ const inputNoteValue = 1000;
+ const outputNoteValue = 500;
+
+ const inputNote = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const outputNote1 = await createNote(outputNoteValue, sender.address, [
+ sender.address,
+ ]);
+
+ const outputNote2 = await createNote(
+ outputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const badProofData = new JoinSplitProof(
+ [inputNote],
+ [outputNote1, outputNote2],
+ streamUtilitiesMock.address,
+ 0,
+ sender.address
+ ).encodeABI(zkAsset.address);
+
+ const streamObject = {
+ ...streamObjectTemplate,
+ // Here we pass the output note hash as the stream note hash
+ // This should invalidate the proof.
+ noteHash: outputNote1.noteHash,
+ };
+
+ await expect(
+ streamUtilitiesMock.validateJoinSplitProof(
+ ace.address,
+ badProofData,
+ outputNote1.noteHash,
+ streamObject
+ )
+ ).to.be.revertedWith('stream note in 2 is not correct');
});
- it('reverts if proof has a non-zero public value transfer');
- it('reverts if proof does not have one input note only');
- it('reverts if proof does not have two output notes only');
- it('reverts if proof does not use same withdraw note as dividend proof');
- it('reverts if proof does not use stream note as input');
it('returns output notes of proof');
});
diff --git a/packages/contracts/test/StreamUtilities/validateRatioProof.js b/packages/contracts/test/StreamUtilities/validateRatioProof.js
index 51b68e1..382b4b5 100644
--- a/packages/contracts/test/StreamUtilities/validateRatioProof.js
+++ b/packages/contracts/test/StreamUtilities/validateRatioProof.js
@@ -1,6 +1,8 @@
const { waffle } = require('@nomiclabs/buidler');
-const { use } = require('chai');
+const { use, expect } = require('chai');
const { solidity, createFixtureLoader } = require('ethereum-waffle');
+const { DividendProof } = require('aztec.js');
+const { createNote } = require('../helpers/notes/createNote');
const { StreamUtilitiesFixture } = require('../fixtures');
use(solidity);
@@ -10,13 +12,193 @@ describe('StreamUtilities - validateRatioProof', function () {
const [sender, recipient] = provider.getWallets();
const loadFixture = createFixtureLoader(provider, [sender, recipient]);
- // eslint-disable-next-line no-unused-vars
+ let ace;
let streamUtilitiesMock;
+ let streamObjectTemplate;
+ let zkAsset;
beforeEach(async function () {
- ({ streamUtilitiesMock } = await loadFixture(StreamUtilitiesFixture));
+ ({ ace, streamUtilitiesMock, zkAsset } = await loadFixture(
+ StreamUtilitiesFixture
+ ));
+ streamObjectTemplate = {
+ recipient: recipient.address,
+ sender: sender.address,
+ tokenAddress: zkAsset.address,
+ isEntity: true,
+ };
});
- it('reverts if proof ratio does not match withdrawal duration');
- it('reverts if proof does not use stream note as source');
- it('returns input and output notes of proof');
+ it('reverts if proof ratio does not match withdrawal duration', async function () {
+ const inputNoteValue = 1000;
+
+ const streamTotalDuration = 100;
+ const withdrawalDuration = 10;
+
+ // We may then withdraw 1/10th of the note's value, i.e. 100
+ // Instead we try to take half
+ const withdrawNoteValue = 500;
+ const remainderNoteValue = 0;
+ const ratioNumerator = 1;
+ const ratioDenominator = 2;
+
+ const inputNote = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const withdrawNote = await createNote(
+ withdrawNoteValue,
+ sender.address,
+ [sender.address]
+ );
+
+ const remainderNote = await createNote(
+ remainderNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const badProofData = new DividendProof(
+ inputNote,
+ remainderNote,
+ withdrawNote,
+ streamUtilitiesMock.address,
+ ratioDenominator,
+ ratioNumerator
+ ).encodeABI();
+
+ const streamObject = {
+ ...streamObjectTemplate,
+ noteHash: inputNote.noteHash,
+ startTime: 0,
+ lastWithdrawTime: 0,
+ stopTime: streamTotalDuration,
+ };
+
+ await expect(
+ streamUtilitiesMock.validateRatioProof(
+ ace.address,
+ badProofData,
+ withdrawalDuration,
+ streamObject
+ )
+ ).to.be.revertedWith('ratios do not match');
+ });
+
+ it('reverts if proof does not use stream note as source', async function () {
+ const inputNoteValue = 1000;
+
+ const streamTotalDuration = 100;
+ const withdrawalDuration = 10;
+
+ // We may then withdraw 1/10th of the note's value, i.e. 100
+ const withdrawNoteValue = 100;
+ const remainderNoteValue = 0;
+ const ratioNumerator = 1;
+ const ratioDenominator = 10;
+
+ const inputNote = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const withdrawNote = await createNote(
+ withdrawNoteValue,
+ sender.address,
+ [sender.address]
+ );
+
+ const remainderNote = await createNote(
+ remainderNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const badProofData = new DividendProof(
+ inputNote,
+ remainderNote,
+ withdrawNote,
+ streamUtilitiesMock.address,
+ ratioDenominator,
+ ratioNumerator
+ ).encodeABI();
+
+ const streamObject = {
+ ...streamObjectTemplate,
+ noteHash: withdrawNote.noteHash,
+ startTime: 0,
+ lastWithdrawTime: 0,
+ stopTime: streamTotalDuration,
+ };
+
+ await expect(
+ streamUtilitiesMock.validateRatioProof(
+ ace.address,
+ badProofData,
+ withdrawalDuration,
+ streamObject
+ )
+ ).to.be.revertedWith('incorrect notional note in proof 1');
+ });
+
+ it('returns withdrawal note hash', async function () {
+ const inputNoteValue = 1000;
+
+ const streamTotalDuration = 100;
+ const withdrawalDuration = 10;
+
+ // We may then withdraw 1/10th of the note's value, i.e. 100
+ const withdrawNoteValue = 100;
+ const remainderNoteValue = 0;
+ const ratioNumerator = 1;
+ const ratioDenominator = 10;
+
+ const inputNote = await createNote(
+ inputNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const withdrawNote = await createNote(
+ withdrawNoteValue,
+ sender.address,
+ [sender.address]
+ );
+
+ const remainderNote = await createNote(
+ remainderNoteValue,
+ streamUtilitiesMock.address,
+ [sender.address]
+ );
+
+ const proofData = new DividendProof(
+ inputNote,
+ remainderNote,
+ withdrawNote,
+ streamUtilitiesMock.address,
+ ratioDenominator,
+ ratioNumerator
+ ).encodeABI();
+
+ const streamObject = {
+ ...streamObjectTemplate,
+ noteHash: inputNote.noteHash,
+ startTime: 0,
+ lastWithdrawTime: 0,
+ stopTime: streamTotalDuration,
+ };
+
+ await expect(
+ streamUtilitiesMock.validateRatioProof(
+ ace.address,
+ proofData,
+ withdrawalDuration,
+ streamObject
+ )
+ )
+ .to.emit(streamUtilitiesMock, 'ValidateRatioProof')
+ .withArgs(withdrawNote.noteHash);
+ });
});
diff --git a/packages/contracts/test/fixtures.js b/packages/contracts/test/fixtures.js
index f3f5b01..7d11278 100644
--- a/packages/contracts/test/fixtures.js
+++ b/packages/contracts/test/fixtures.js
@@ -1,5 +1,4 @@
const { ethers } = require('ethers');
-
const { deployContract } = require('ethereum-waffle');
const bn128 = require('@aztec/bn128');
@@ -71,7 +70,37 @@ async function zkAssetFixture(provider, [wallet]) {
1,
]);
- // ethers.errors.setLogLevel('warn');
+ // const depositAmount = '10000000000000';
+
+ // await token.mint(wallet.address, depositAmount);
+ // await token.approve(ace.address, depositAmount);
+
+ // const {
+ // depositInputNotes,
+ // depositOutputNotes,
+ // depositPublicValue,
+ // depositInputOwnerAccounts,
+ // } = await getDepositNotes([100000], wallet.address);
+ // const publicValue = depositPublicValue * -1;
+
+ // const proof = new JoinSplitProof(
+ // depositInputNotes,
+ // depositOutputNotes,
+ // wallet.address,
+ // publicValue,
+ // wallet.address
+ // );
+ // const data = proof.encodeABI(zkAsset.address);
+ // const signatures = proof.constructSignatures(
+ // zkAsset.address,
+ // depositInputOwnerAccounts
+ // );
+
+ // // Approve ACE to spend tokens held by the zkAsset contract
+ // await ace.publicApprove(zkAsset.address, proof.hash, 100000);
+
+ // // convert some of sender's assets to zkAssets
+ // await zkAsset['confidentialTransfer(bytes,bytes)'](data, signatures);
return {
ace,
@@ -80,6 +109,7 @@ async function zkAssetFixture(provider, [wallet]) {
baseFactory,
token,
zkAsset,
+ // depositOutputNotes,
};
}
@@ -94,6 +124,7 @@ async function noteStreamFixture(provider, [wallet]) {
baseFactory,
token,
zkAsset,
+ depositOutputNotes,
} = await zkAssetFixture(provider, [wallet]);
const noteStream = await deployContract(wallet, NoteStream, [ace.address]);
@@ -106,6 +137,7 @@ async function noteStreamFixture(provider, [wallet]) {
token,
zkAsset,
noteStream,
+ depositOutputNotes,
};
}
@@ -120,6 +152,7 @@ async function StreamUtilitiesFixture(provider, [wallet]) {
baseFactory,
token,
zkAsset,
+ depositOutputNotes,
} = await zkAssetFixture(provider, [wallet]);
const streamUtilitiesMock = await deployContract(
@@ -134,6 +167,7 @@ async function StreamUtilitiesFixture(provider, [wallet]) {
baseFactory,
token,
zkAsset,
+ depositOutputNotes,
streamUtilitiesMock,
};
}
diff --git a/packages/contracts/test/helpers/constants.js b/packages/contracts/test/helpers/constants.js
new file mode 100644
index 0000000..d42ab67
--- /dev/null
+++ b/packages/contracts/test/helpers/constants.js
@@ -0,0 +1,6 @@
+// Adding an address to the metadata requires a public key however as we are not decrypting notes from the registry
+// we do not need to use a proper public key. We then use a constant dummy value.
+const dummyLinkedPublicKey =
+ '0xa61d17b0dd3095664d264628a6b947721314b6999aa6a73d3c7698f041f78a4d';
+
+module.exports = { dummyLinkedPublicKey };
diff --git a/packages/contracts/test/helpers/deposit/streamNote.js b/packages/contracts/test/helpers/deposit/streamNote.js
new file mode 100644
index 0000000..2e77c12
--- /dev/null
+++ b/packages/contracts/test/helpers/deposit/streamNote.js
@@ -0,0 +1,51 @@
+const { JoinSplitProof } = require('aztec.js');
+const { createNote } = require('../notes/createNote');
+
+/**
+ * Generate a note such that would be owned by the NoteStream contract, given the desired note value and stream sender/recipients
+ *
+ * @method getStreamNote
+ * @param {Number} noteValue - Number representing note value
+ * @param {Object} sender - Ethereum account that initiated the stream
+ * @param {Object} recipient - Ethereum account that is receiving the stream
+ * @returns {Note} - stream note
+ */
+const getStreamNote = (noteValue, noteOwner, sender, recipient) => {
+ return createNote(noteValue, noteOwner, [sender, recipient]);
+};
+
+const createStreamDepositProof = async (
+ inputNotes,
+ noteOwner,
+ sender,
+ recipient,
+ publicValue
+) => {
+ // console.log(sender, recipient);
+ const depositInputOwnerAccounts = new Array(inputNotes.length).fill(sender);
+
+ const noteValue = inputNotes
+ .map((noteObj) => noteObj.k.toNumber())
+ .reduce((a, b) => a + b, 0);
+
+ const streamNote = await getStreamNote(
+ noteValue,
+ noteOwner,
+ sender,
+ recipient
+ );
+ const depositProof = new JoinSplitProof(
+ inputNotes,
+ [streamNote],
+ sender,
+ publicValue,
+ sender
+ );
+ return {
+ depositProof,
+ depositInputOwnerAccounts,
+ streamNote,
+ };
+};
+
+module.exports = { getStreamNote, createStreamDepositProof };
diff --git a/packages/contracts/test/helpers/mint/getDepositNotes.js b/packages/contracts/test/helpers/mint/getDepositNotes.js
new file mode 100644
index 0000000..b71d501
--- /dev/null
+++ b/packages/contracts/test/helpers/mint/getDepositNotes.js
@@ -0,0 +1,41 @@
+const { getNotesForAccount } = require('../notes/getNotesForAccount');
+
+/**
+ * General purpose function that generates a set of notes to be used in a deposit join split proof.
+ *
+ * There are no inputNotes created in this function - it generates notes for a deposit proof i.e. a joinSplit
+ * where tokens are being converted into notes.
+ *
+ * Output notes are created. The values of these output notes is determined by the input argument
+ * depositOutputNoteValues
+ *
+ * @method getDepositNotes
+ * @param {Number[]} depositOutputNoteValues - array of note values, for which notes will be created
+ * @param {Number[]} depositOwnerPrivateKey - private key for address which will own the created notes
+ * @returns {Note[]} depositInputNotes - input notes for a deposit join split proof
+ * @returns {Note[]} depositOutputNotes - output notes for a deposit join split proof
+ * @returns {Object[]} depositInputOwnerAccounts - Ethereum accounts of the input note owners
+ * @returns {Object[]} depositOutputOwnerAccounts - Ethereum accounts of the output note owners
+ */
+const getDepositNotes = async (
+ depositOutputNoteValues,
+ depositOwnerAddress
+) => {
+ const depositInputNotes = [];
+ const depositOutputNotes = await getNotesForAccount(
+ depositOwnerAddress,
+ depositOutputNoteValues
+ );
+ const depositPublicValue = depositOutputNoteValues.reduce((a, b) => a + b);
+ const depositInputOwnerAccounts = [];
+ const depositOutputOwnerAccounts = [depositOwnerAddress];
+ return {
+ depositInputNotes,
+ depositOutputNotes,
+ depositPublicValue,
+ depositInputOwnerAccounts,
+ depositOutputOwnerAccounts,
+ };
+};
+
+module.exports = { getDepositNotes };
diff --git a/packages/contracts/test/helpers/mint/mintZkAssets.js b/packages/contracts/test/helpers/mint/mintZkAssets.js
new file mode 100644
index 0000000..3007205
--- /dev/null
+++ b/packages/contracts/test/helpers/mint/mintZkAssets.js
@@ -0,0 +1,35 @@
+const { JoinSplitProof } = require('aztec.js');
+const { getDepositNotes } = require('./getDepositNotes');
+
+const mintZkAsset = async (recipientAddress, amount, token, zkAsset, ace) => {
+ const signerAddress = token.signer.address;
+ // Mint public tokens and give ACE access to move them
+ await token.mint(signerAddress, amount);
+ await token.approve(ace.address, amount);
+
+ const {
+ depositInputNotes,
+ depositOutputNotes,
+ depositPublicValue,
+ } = await getDepositNotes([amount], recipientAddress);
+ const publicValue = depositPublicValue * -1;
+
+ const proof = new JoinSplitProof(
+ depositInputNotes,
+ depositOutputNotes,
+ signerAddress,
+ publicValue,
+ signerAddress
+ );
+ const data = proof.encodeABI(zkAsset.address);
+
+ // Approve ACE to spend tokens held by the zkAsset contract
+ await ace.publicApprove(zkAsset.address, proof.hash, amount);
+
+ // Note: As there are no input notes we can use an empty signature
+ await zkAsset['confidentialTransfer(bytes,bytes)'](data, '0x');
+
+ return depositOutputNotes[0];
+};
+
+module.exports = { mintZkAsset };
diff --git a/packages/contracts/test/helpers/notes/createNote.js b/packages/contracts/test/helpers/notes/createNote.js
new file mode 100644
index 0000000..ebc45ba
--- /dev/null
+++ b/packages/contracts/test/helpers/notes/createNote.js
@@ -0,0 +1,17 @@
+const { note } = require('aztec.js');
+const secp256k1 = require('@aztec/secp256k1');
+const { dummyLinkedPublicKey } = require('../constants');
+
+const createNote = (noteValue, noteOwner, access) => {
+ return note.create(
+ secp256k1.generateAccount().publicKey,
+ noteValue,
+ access.map((address) => ({
+ address,
+ linkedPublicKey: dummyLinkedPublicKey,
+ })),
+ noteOwner
+ );
+};
+
+module.exports = { createNote };
diff --git a/packages/contracts/test/helpers/notes/getNotesForAccount.js b/packages/contracts/test/helpers/notes/getNotesForAccount.js
new file mode 100644
index 0000000..b9a6d8c
--- /dev/null
+++ b/packages/contracts/test/helpers/notes/getNotesForAccount.js
@@ -0,0 +1,17 @@
+const { createNote } = require('./createNote');
+
+/**
+ * Generate a set of notes, given the desired note values and account of the owner
+ *
+ * @method getNotesForAccount
+ * @param {Object} aztecAccount - Ethereum account that owns the notes to be created
+ * @param {Number[]} noteValues - array of note values, for which notes will be created
+ * @returns {Note[]} - array of notes
+ */
+const getNotesForAccount = async (address, noteValues) => {
+ return Promise.all(
+ noteValues.map((noteValue) => createNote(noteValue, address, [address]))
+ );
+};
+
+module.exports = { getNotesForAccount };
diff --git a/packages/contracts/test/helpers/signProof.js b/packages/contracts/test/helpers/signProof.js
new file mode 100644
index 0000000..c77c9ae
--- /dev/null
+++ b/packages/contracts/test/helpers/signProof.js
@@ -0,0 +1,15 @@
+const { signer } = require('aztec.js');
+
+const signProof = (zkAsset, proof, spender, privateKey) => {
+ const data = proof.encodeABI(zkAsset.address);
+ const signature = signer.signApprovalForProof(
+ zkAsset.address,
+ proof.eth.outputs,
+ spender,
+ true,
+ privateKey
+ );
+ return { data, signature };
+};
+
+module.exports = { signProof };
diff --git a/packages/contracts/test/helpers/transfer/getTransferNotes.js b/packages/contracts/test/helpers/transfer/getTransferNotes.js
new file mode 100644
index 0000000..0f34022
--- /dev/null
+++ b/packages/contracts/test/helpers/transfer/getTransferNotes.js
@@ -0,0 +1,51 @@
+const { getNotesForAccount } = require('../notes/getNotesForAccount');
+
+/**
+ * General purpose function that generates a set of notes to be used in a deposit joinSplit proof
+ * followed by a transfer joinSplit proof.
+ *
+ * The scenario is that a deposit proof is being performed, followed by a transfer proof.
+ * In the deposit proof, public tokens are being converted into notes.
+ *
+ * These notes are then the input to a transfer proof, where notes are transferred to a second user.
+ * During this proof, some note value is also converted back into public token form and withdrawn.
+ *
+ * The value of the notes created and involved in the proofs is controlled through the two input arguments:
+ * depositOutputNoteValues and transferOutputNoteValues
+ *
+ * @method getDepositAndTransferNotes
+ * @param {Number[]} transferInputNoteValues - output note values for the deposit proof
+ * @param {Number[]} transferOutputNoteValues - output note values for the transfer proof
+ * @param {Number[]} transferInputNoteValues - output note values for the deposit proof
+ * @param {Number[]} transferOutputNoteValues - output note values for the transfer proof
+ * @returns {Note[]} transferInputNotes - inputs for a transfer join split proof
+ * @returns {Note[]} transferOutputNotes - output notes for a transfer join split proof
+ * @returns {Object[]} transferInputOwnerAccounts - Ethereum accounts of the transfer input note owners
+ * @returns {Object[]} transferOutputOwnerAccounts - Ethereum accounts of the transfer output note owners
+ */
+const getTransferNotes = async (
+ transferInputNotes,
+ transferOutputNoteValues,
+ senderAddress,
+ recipientAddress
+) => {
+ const transferInputOwnerAccounts = new Array(
+ transferInputNotes.length
+ ).fill(senderAddress);
+
+ const transferOutputNotes = await getNotesForAccount(
+ recipientAddress,
+ transferOutputNoteValues
+ );
+ const transferOutputOwnerAccounts = new Array(
+ transferOutputNotes.length
+ ).fill(recipientAddress);
+ return {
+ transferInputNotes,
+ transferOutputNotes,
+ transferInputOwnerAccounts,
+ transferOutputOwnerAccounts,
+ };
+};
+
+module.exports = { getTransferNotes };
diff --git a/packages/react-app/.env b/packages/react-app/.env
index e7891d5..7369761 100644
--- a/packages/react-app/.env
+++ b/packages/react-app/.env
@@ -1,3 +1,5 @@
+BROWSER=none
+
REACT_APP_SUBGRAPH_URL='https://api.thegraph.com/subgraphs/name/tomafrench/notestream-rinkeby'
REACT_APP_AZTEC_API_KEY = '9HRKN7S-JSZMRJM-KWSDWSY-B2VSRD9'
REACT_APP_TRANSAK_API_KEY = '7acc4227-1611-4787-8349-8b32194b6dc1'
diff --git a/packages/react-app/package.json b/packages/react-app/package.json
index 2e8007c..add9c78 100644
--- a/packages/react-app/package.json
+++ b/packages/react-app/package.json
@@ -11,25 +11,26 @@
"url": "https://github.com/TomAFrench/NoteStream/issues"
},
"dependencies": {
- "@apollo/client": "^3.0.0-beta.41",
+ "@apollo/client": "^3.0.2",
"@aztec/secp256k1": "^1.2.0",
- "@material-ui/core": "^4.9.5",
+ "@ethersproject/address": "^5.0.2",
+ "@ethersproject/bignumber": "^5.0.5",
+ "@ethersproject/contracts": "^5.0.2",
+ "@ethersproject/providers": "^5.0.5",
+ "@ethersproject/units": "^5.0.2",
+ "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@notestream/contract-artifacts": "^1.0.1",
- "@transak/transak-sdk": "^1.0.17",
- "@types/testing-library__dom": "^7.5.0",
- "aztec.js": "^0.17.0",
- "bn.js": "^5.1.1",
- "bnc-onboard": "^1.9.0",
- "ethers": "^4.0.46",
- "graphql": "^14.6.0",
- "moment": "^2.24.0",
+ "bn.js": "^5.1.2",
+ "bnc-onboard": "^1.10.3",
+ "graphql": "^15.3.0",
+ "moment": "^2.27.0",
"prop-types": "^15.7.2",
- "react": "^16.13.0",
+ "react": "^16.13.1",
"react-blockies": "^1.4.1",
"react-copy-to-clipboard": "^5.0.2",
"react-dom": "^16.13.0",
- "react-router": "^5.1.2",
+ "react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "^3.4.1",
"zkasset-metadata": "^0.2.0"
@@ -46,17 +47,18 @@
"@types/bn.js": "^4.11.6",
"@types/react-copy-to-clipboard": "^4.3.0",
"@types/react-router-dom": "^5.1.5",
+ "@types/testing-library__dom": "^7.5.0",
"@typescript-eslint/eslint-plugin-tslint": "^2.27.0",
- "eslint": "^6.8.0",
- "eslint-config-airbnb-base": "^14.1.0",
- "eslint-config-prettier": "^6.10.1",
- "eslint-plugin-import": "^2.20.2",
- "eslint-plugin-prettier": "^3.1.2",
- "eslint-plugin-react": "^7.19.0",
+ "eslint": "^7.5.0",
+ "eslint-config-airbnb-base": "^14.2.0",
+ "eslint-config-prettier": "^6.11.0",
+ "eslint-plugin-import": "^2.22.0",
+ "eslint-plugin-prettier": "^3.1.4",
+ "eslint-plugin-react": "^7.20.3",
"lint-staged": "^10.2.2",
"prettier": "^2.0.4",
"shx": "^0.3.2",
- "typescript": "^3.8.3"
+ "typescript": "^3.9.7"
},
"scripts": {
"precommit": "lint-staged",
diff --git a/packages/react-app/src/App.tsx b/packages/react-app/src/App.tsx
index 2f91b88..5e8e4c0 100644
--- a/packages/react-app/src/App.tsx
+++ b/packages/react-app/src/App.tsx
@@ -12,8 +12,7 @@ import {
getContractAddressesForNetwork,
abis,
} from '@notestream/contract-artifacts';
-import { Contract } from 'ethers';
-import { Web3Provider } from 'ethers/providers';
+import { Contract } from '@ethersproject/contracts';
import { useWalletProvider, useNetwork } from './contexts/OnboardContext';
@@ -74,11 +73,10 @@ const App = (): ReactElement => {
useEffect(() => {
if (appNetworkId && provider) {
const { NoteStream } = getContractAddressesForNetwork(appNetworkId);
- const signer = new Web3Provider(provider).getSigner();
const noteStreamContract = new Contract(
NoteStream,
abis.NoteStream,
- signer,
+ provider.getSigner(),
);
setStreamContract(noteStreamContract);
}
diff --git a/packages/react-app/src/components/Link.tsx b/packages/react-app/src/components/Link.tsx
index a826efd..487fda0 100644
--- a/packages/react-app/src/components/Link.tsx
+++ b/packages/react-app/src/components/Link.tsx
@@ -1,16 +1,29 @@
import React, { ReactElement } from 'react';
+import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import isExternal from '../utils/links';
-const flexLink = (props: any): ReactElement => {
- return isExternal(props.to) ? (
-
- {props.children}
+interface Props {
+ to: string;
+ children: any;
+ [x: string]: any;
+}
+
+const FlexLink = ({ to, children, ...rest }: Props): ReactElement =>
+ isExternal(to) ? (
+
+ {children}
) : (
- {props.children}
+
+ {children}
+
);
+
+FlexLink.propTypes = {
+ to: PropTypes.string.isRequired,
+ children: PropTypes.node.isRequired,
};
-export default flexLink;
+export default FlexLink;
diff --git a/packages/react-app/src/components/Sidebar/SideBarLinks.tsx b/packages/react-app/src/components/Sidebar/SideBarLinks.tsx
index 4e3579d..b1ebc50 100644
--- a/packages/react-app/src/components/Sidebar/SideBarLinks.tsx
+++ b/packages/react-app/src/components/Sidebar/SideBarLinks.tsx
@@ -1,5 +1,4 @@
-import React, { ReactElement, useEffect, useState } from 'react';
-import { useTheme } from '@material-ui/core/styles';
+import React, { ReactElement } from 'react';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
@@ -9,17 +8,12 @@ import Divider from '@material-ui/core/Divider';
import HomeIcon from '@material-ui/icons/Home';
import LocalAtmIcon from '@material-ui/icons/LocalAtm';
import AccountBalanceWalletIcon from '@material-ui/icons/AccountBalanceWallet';
-import ShoppingCartIcon from '@material-ui/icons/ShoppingCart';
import SwapHorizIcon from '@material-ui/icons/SwapHoriz';
import HelpIcon from '@material-ui/icons/Help';
import GitHubIcon from '@material-ui/icons/GitHub';
-import TransakSDK from '@transak/transak-sdk';
import Link from '../Link';
-import setupTransak from '../../utils/transak';
-import { useAddress } from '../../contexts/OnboardContext';
-
const mainLinks = [
{ text: 'Home', icon: , url: '/' },
{ text: 'Convert assets', icon: , url: '/exchange' },
@@ -55,42 +49,26 @@ const NavLinkItem = ({
);
-const SideBarLinks = (): ReactElement => {
- const theme = useTheme();
- const userAddress = useAddress();
- const [transak, setTransak] = useState();
-
- useEffect(() => {
- setTransak(setupTransak(userAddress, theme.palette.primary.main));
- }, [userAddress, theme.palette.primary.main]);
-
- return (
-
- {mainLinks.map((link, index) => (
-
- ))}
-
- => transak.init()}>
-
-
-
-
-
- {secondaryLinks.map((link, index) => (
-
- ))}
-
- );
-};
+const SideBarLinks = (): ReactElement => (
+
+ {mainLinks.map((link, index) => (
+
+ ))}
+
+ {secondaryLinks.map((link, index) => (
+
+ ))}
+
+);
export default SideBarLinks;
diff --git a/packages/react-app/src/components/StreamTable/StreamRow.tsx b/packages/react-app/src/components/StreamTable/StreamRow.tsx
index 0bb586d..61b0a19 100644
--- a/packages/react-app/src/components/StreamTable/StreamRow.tsx
+++ b/packages/react-app/src/components/StreamTable/StreamRow.tsx
@@ -7,7 +7,7 @@ import TableRow from '@material-ui/core/TableRow';
import moment from 'moment';
-import { Contract } from 'ethers';
+import { Contract } from '@ethersproject/contracts';
import { withdrawFunds, cancelStream } from '../../utils/stream';
import { Stream, ZkNote } from '../../types/types';
@@ -83,16 +83,16 @@ const StreamRow = ({
{`${displayValue} ${zkAsset.symbol}`}
- {moment.unix(startTime).format('MMM D, YYYY - HH:mm')}
+ {moment.unix(parseInt(startTime, 10)).format('MMM D, YYYY - HH:mm')}
- {moment.unix(stopTime).format('MMM D, YYYY - HH:mm')}
+ {moment.unix(parseInt(stopTime, 10)).format('MMM D, YYYY - HH:mm')}
{button}
diff --git a/packages/react-app/src/components/StreamTable/index.tsx b/packages/react-app/src/components/StreamTable/index.tsx
index d0c33d5..f319108 100644
--- a/packages/react-app/src/components/StreamTable/index.tsx
+++ b/packages/react-app/src/components/StreamTable/index.tsx
@@ -5,7 +5,7 @@ import TableCell from '@material-ui/core/TableCell';
import TableRow from '@material-ui/core/TableRow';
import { useQuery } from '@apollo/client';
-import { Contract } from 'ethers';
+import { Contract } from '@ethersproject/contracts';
import { Button, Grid, CircularProgress } from '@material-ui/core';
import { generateColumns, STREAM_TABLE_ID, Column } from '../Table/columns';
import { cellWidth } from '../Table/TableHead';
@@ -54,10 +54,10 @@ const humanReadableStream = (stream: Stream): HumanReadableStream => {
zkAsset,
} = stream;
const humanStartTime: string = moment
- .unix(startTime)
+ .unix(parseInt(startTime, 10))
.format('MMM D, YYYY - HH:mm');
const humanStopTime: string = moment
- .unix(stopTime)
+ .unix(parseInt(stopTime, 10))
.format('MMM D, YYYY - HH:mm');
const humanDeposit = '';
@@ -119,9 +119,9 @@ function NewStreamTable({
const tableContents: TableRowData[] = streamInProgress.map(
(stream: Stream) => ({
...humanReadableStream(stream),
- humanStartTimeOrder: stream.startTime,
- humanStopTimeOrder: stream.stopTime,
- humanLastWithdrawTimeOrder: stream.lastWithdrawTime,
+ humanStartTimeOrder: parseInt(stream.startTime, 10),
+ humanStopTimeOrder: parseInt(stream.stopTime, 10),
+ humanLastWithdrawTimeOrder: parseInt(stream.lastWithdrawTime, 10),
}),
);
return (
diff --git a/packages/react-app/src/components/Table/TableHead.tsx b/packages/react-app/src/components/Table/TableHead.tsx
index 39247e9..71ae749 100644
--- a/packages/react-app/src/components/Table/TableHead.tsx
+++ b/packages/react-app/src/components/Table/TableHead.tsx
@@ -19,7 +19,7 @@ export const cellWidth = (width?: number): object | undefined => {
function TableHeader(props: any): ReactElement {
const { columns, order, orderBy, onSort } = props;
- const changeSort = (property: string, orderAttr: boolean) => () => {
+ const changeSort = (property: string, orderAttr: boolean) => (): void => {
onSort(property, orderAttr);
};
diff --git a/packages/react-app/src/components/form/AddressInput.tsx b/packages/react-app/src/components/form/AddressInput.tsx
index e2def73..3d25a64 100644
--- a/packages/react-app/src/components/form/AddressInput.tsx
+++ b/packages/react-app/src/components/form/AddressInput.tsx
@@ -1,5 +1,5 @@
import React, { ReactElement, useState, useEffect } from 'react';
-import { utils } from 'ethers';
+import { getAddress } from '@ethersproject/address';
import TextField from '@material-ui/core/TextField';
import { Address, AztecSDK } from '../../types/types';
@@ -20,7 +20,7 @@ const AddressInput = (props: any): ReactElement => {
useEffect(() => {
const checkAddressIsValid = async (testAddress: Address): Promise => {
try {
- if (utils.getAddress(testAddress)) {
+ if (getAddress(testAddress)) {
const user = await aztec.user(testAddress);
setInvalidAddress(!user.registered);
}
diff --git a/packages/react-app/src/components/modals/CreateStreamModal.tsx b/packages/react-app/src/components/modals/CreateStreamModal.tsx
index f908872..704b0c2 100644
--- a/packages/react-app/src/components/modals/CreateStreamModal.tsx
+++ b/packages/react-app/src/components/modals/CreateStreamModal.tsx
@@ -11,8 +11,7 @@ import DialogTitle from '@material-ui/core/DialogTitle';
import Grid from '@material-ui/core/Grid';
import moment from 'moment';
-import { Contract } from 'ethers';
-import { Web3Provider } from 'ethers/providers';
+import { Contract } from '@ethersproject/contracts';
import { createStream } from '../../utils/stream';
import AddressInput from '../form/AddressInput';
@@ -85,7 +84,7 @@ export default function CreateStreamDialog({
const linkedToken = new Contract(
zkAsset.linkedTokenAddress,
ERC20.abi,
- new Web3Provider(provider),
+ provider,
);
const tokenSymbol = linkedToken.symbol();
const tokenDecimals = linkedToken.decimals();
@@ -219,14 +218,6 @@ export default function CreateStreamDialog({
-
- After you click "Create Stream", you will be asked to
- sign two transactions. The first sends the AZTEC note to the
- NoteStream contract and the second creates the stream.
-
-
- In a later update, these two transactions will be combined.
-
@@ -235,21 +226,26 @@ export default function CreateStreamDialog({