Address Contract Partially Verified
Address
0xD49Da05aef8077CC6824e3B84493D6491f452B0A
Balance
0 ETH
Nonce
45
Code Size
13346 bytes
Creator
0xfbbDEc9B...5980 at tx 0x025a7179...912b5b
Indexed Transactions
0 (45 on-chain, 0.8% indexed)
Contract Bytecode
13346 bytes
0x608060405260043610620000f25760003560e01c80638117abc1116200008b578063afa3363d1162000061578063afa3363d1462000235578063c0fd43b4146200025c578063f77c47911462000281578063fddf851f146200029957620000f2565b80638117abc114620001d357806389b08f1114620001eb57806390502c2e146200021057620000f2565b80632d621c5111620000cd5780632d621c5114620001575780633644e515146200017e57806351b42b0014620001965780635a1db8c414620001ae57620000f2565b80630ab9ad3314620000f75780630f15f4c014620001105780631180ef4a1462000128575b600080fd5b6200010e62000108366004620023c6565b620002be565b005b3480156200011d57600080fd5b506200010e62000600565b6200013f6200013936600462002235565b62000643565b6040516200014e91906200270e565b60405180910390f35b3480156200016457600080fd5b506200016f62000871565b6040516200014e9190620027ea565b3480156200018b57600080fd5b506200016f6200088a565b348015620001a357600080fd5b506200010e62000890565b348015620001bb57600080fd5b506200010e620001cd366004620021f8565b620008d3565b348015620001e057600080fd5b506200013f62000a1a565b348015620001f857600080fd5b506200016f6200020a366004620021ba565b62000a29565b3480156200021d57600080fd5b506200010e6200022f366004620022ea565b62000a3b565b3480156200024257600080fd5b506200024d62000c7e565b6040516200014e9190620027a6565b3480156200026957600080fd5b506200016f6200027b366004620021ba565b62000c83565b3480156200028e57600080fd5b506200013f62000c9e565b348015620002a657600080fd5b506200013f620002b8366004620021ba565b62000cad565b42841015620002ea5760405162461bcd60e51b8152600401620002e19062002b1e565b60405180910390fd5b620002f462001fa8565b506040805160a08101825284516001600160a01b0390811682526020808701519083015285830151928201839052606080870151908301526080808701519091169082015290620003595760405162461bcd60e51b8152600401620002e19062002942565b6000620003668862000cd4565b9050600062000405600154620003ff604051806101600160405280866001600160a01b03168152602001306001600160a01b031681526020013481526020018d81526020018c81526020018b815260200187600001516001600160a01b0316815260200187602001518152602001876040015181526020018760600151815260200187608001516001600160a01b031681525062000d36565b62000dc9565b905062000414828a8662000e1a565b620004335760405162461bcd60e51b8152600401620002e19062002acb565b6200044681858763ffffffff62000edb16565b620004655760405162461bcd60e51b8152600401620002e19062002bb7565b6200047282898362000fc9565b3415620004995762000497345a6001600160a01b038516919063ffffffff620010d516565b505b620004d261ea60603f620004bc604087604001516200111590919063ffffffff16565b81620004c457fe5b049063ffffffff6200114e16565b5a1015620004f45760405162461bcd60e51b8152600401620002e19062002b67565b60005a905060006060306001600160a01b031686604001518d6040516200051c91906200256d565b60006040518083038160008787f1925050503d80600081146200055c576040519150601f19603f3d011682016040523d82523d6000602084013e62000561565b606091505b50915091505a604087015193039283106200058157856040015162000583565b825b9250846001600160a01b0316336001600160a01b03167f4d3367ceeab65bf3b68cc4658d780a0f6e4101b2475aa8b6658c2df7851e12bb8d87878787604051620005d295949392919062002c09565b60405180910390a3602086015115620005f257620005f285878562001174565b505050505050505050505050565b336200060c816200124b565b6040516001600160a01b038216907f0cc43938d137e7efade6a531f663e78c1fc75257b0d65ffda2fdaf70cb49cdf990600090a250565b6000805415620006675760405162461bcd60e51b8152600401620002e190620028bf565b60016000558733301480620006845750336001600160a01b038216145b620006a35760405162461bcd60e51b8152600401620002e1906200290b565b600254600454620006c3916001600160a01b0390811691168b30620012f2565b91508160005b848110156200076457816001600160a01b0316631ed86f19878784818110620006ee57fe5b9050602002016020810190620007059190620021ba565b6040518263ffffffff1660e01b81526004016200072391906200270e565b600060405180830381600087803b1580156200073e57600080fd5b505af115801562000753573d6000803e3d6000fd5b505060019092019150620006c99050565b5087156200086057600260009054906101000a90046001600160a01b03166001600160a01b0316635a6971f96040518163ffffffff1660e01b815260040160206040518083038186803b158015620007bb57600080fd5b505afa158015620007d0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007f69190620021d9565b6001600160a01b03166358086775848b8b8b8b6040518663ffffffff1660e01b81526004016200082b95949392919062002745565b600060405180830381600087803b1580156200084657600080fd5b505af11580156200085b573d6000803e3d6000fd5b505050505b505060008055979650505050505050565b6040516200087f906200261a565b604051809103902081565b60015481565b336200089c8162001556565b6040516001600160a01b038216907f749cb6b4c510bc468cf6b9c2086d6f0a54d6b18e25d37bf3200e68eab0880c0090600090a250565b60005415620008f65760405162461bcd60e51b8152600401620002e190620028bf565b60016000558133301480620009905750806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200094057600080fd5b505afa15801562000955573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200097b9190620021d9565b6001600160a01b0316336001600160a01b0316145b620009af5760405162461bcd60e51b8152600401620002e19062002a94565b604051631ed86f1960e01b81526001600160a01b03841690631ed86f1990620009dd9085906004016200270e565b600060405180830381600087803b158015620009f857600080fd5b505af115801562000a0d573d6000803e3d6000fd5b5050600080555050505050565b6004546001600160a01b031681565b60036020526000908152604090205481565b6000541562000a5e5760405162461bcd60e51b8152600401620002e190620028bf565b60016000908155600254604080516306a32ffd60e01b815290516001600160a01b03909216916306a32ffd91600480820192602092909190829003018186803b15801562000aab57600080fd5b505afa15801562000ac0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ae69190620021d9565b905060005b8281101562000c7457600084848381811062000b0357fe5b905060200201602081019062000b1a9190620021ba565b90506001600160a01b03811662000b52574762000b4a815a6001600160a01b038716919063ffffffff620010d516565b505062000c6a565b6040516370a0823160e01b81526000906001600160a01b038316906370a082319062000b839030906004016200270e565b60206040518083038186803b15801562000b9c57600080fd5b505afa15801562000bb1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bd79190620024c3565b9050801562000c685760405163a9059cbb60e01b81526001600160a01b0383169063a9059cbb9062000c1090879085906004016200278d565b602060405180830381600087803b15801562000c2b57600080fd5b505af115801562000c40573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c6691906200232e565b505b505b5060010162000aeb565b5050600080555050565b606090565b6001600160a01b031660009081526003602052604090205490565b6002546001600160a01b031681565b600062000cce62000cbe83620015f8565b62000cc86200160d565b62001639565b92915050565b60006308c077a560e11b62000ce98362001648565b6001600160e01b0319161462000d135760405162461bcd60e51b8152600401620002e190620028e3565b600062000d228360006200165c565b905062000d2f8162000cad565b9392505050565b600060405162000d46906200261a565b604051809103902082600001518360200151846040015185606001518051906020012086608001518760a001518860c001518960e001518a61010001518b61012001518c610140015160405160200162000dac9c9b9a99989796959493929190620027f3565b604051602081830303815290604052805190602001209050919050565b600060405180604001604052806002815260200161190160f01b815250838360405160200162000dfc939291906200258b565b60405160208183030381529060405280519060200120905092915050565b60008062000e288462001648565b90506001600160e01b031981166316876e3160e21b141562000ecd5762000ec4856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000e8257600080fd5b505afa15801562000e97573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ebd9190620021d9565b8462001676565b91505062000d2f565b62000ec485828686620016b7565b6000815183511462000f015760405162461bcd60e51b8152600401620002e1906200296d565b6000805b845181101562000fbd57816001600160a01b031685828151811062000f2657fe5b60200260200101516001600160a01b03161162000f575760405162461bcd60e51b8152600401620002e19062002a13565b84818151811062000f6457fe5b6020026020010151915062000fa38686838151811062000f8057fe5b602002602001015186848151811062000f9557fe5b602002602001015162001739565b62000fb45760009250505062000d2f565b60010162000f05565b50600195945050505050565b8162001053576001600160a01b038316600090815260036020908152604080832084845260010190915290205460ff1615620010195760405162461bcd60e51b8152600401620002e19062002b91565b6001600160a01b03831660009081526003602090815260408083208484526001908101909252909120805460ff19169091179055620010d0565b6001600160a01b03831660009081526003602052604090205482116200108d5760405162461bcd60e51b8152600401620002e190620029c3565b43608083901c1115620010b45760405162461bcd60e51b8152600401620002e19062002a42565b6001600160a01b03831660009081526003602052604090208290555b505050565b6000620010f36001600160a01b038516848463ffffffff6200187d16565b90508062000d2f5760405162461bcd60e51b8152600401620002e19062002999565b8181028215806200112f5750818382816200112c57fe5b04145b62000cce5760405162461bcd60e51b8152600401620002e19062002be3565b8181018281101562000cce5760405162461bcd60e51b8152600401620002e19062002af8565b6000620011a58360200151620011988560600151856200114e90919063ffffffff16565b9063ffffffff6200111516565b9050620011b88484600001518362001912565b60808301516000906001600160a01b031615620011da578360800151620011dc565b335b84519091506001600160a01b031662001213576200120c8582846040518060200160405280600081525062001ab5565b5062001244565b62001225858560000151838562001b50565b620012445760405162461bcd60e51b8152600401620002e19062002a6b565b5050505050565b8060606200125862000c7e565b905060005b8151811015620012ec57826001600160a01b031663b149206e8383815181106200128357fe5b6020026020010151306040518363ffffffff1660e01b8152600401620012ab92919062002873565b600060405180830381600087803b158015620012c657600080fd5b505af1158015620012db573d6000803e3d6000fd5b5050600190920191506200125d9050565b50505050565b6000620013136200130384620015f8565b6200130d6200160d565b62001bee565b604051631b2ce7f360e11b81529091506001600160a01b03821690633659cfe690620013449087906004016200270e565b600060405180830381600087803b1580156200135f57600080fd5b505af115801562001374573d6000803e3d6000fd5b50506040516378b9ce5760e11b81526001600160a01b038416925063f1739cae9150620013a69084906004016200270e565b600060405180830381600087803b158015620013c157600080fd5b505af1158015620013d6573d6000803e3d6000fd5b50506040516377b8b1c760e01b81526001600160a01b03841692506377b8b1c791506200140c9088908790879060040162002722565b600060405180830381600087803b1580156200142757600080fd5b505af11580156200143c573d6000803e3d6000fd5b50505050846001600160a01b031663ab7aa6ad6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200147a57600080fd5b505afa1580156200148f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014b59190620021d9565b6001600160a01b031663779beedf826040518263ffffffff1660e01b8152600401620014e291906200270e565b600060405180830381600087803b158015620014fd57600080fd5b505af115801562001512573d6000803e3d6000fd5b50506040516001600160a01b038087169350841691507f5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f08190600090a3949350505050565b8060606200156362000c7e565b905060005b8151811015620012ec57826001600160a01b031663b149206e8383815181106200158e57fe5b602002602001015160006040518363ffffffff1660e01b8152600401620015b792919062002873565b600060405180830381600087803b158015620015d257600080fd5b505af1158015620015e7573d6000803e3d6000fd5b505060019092019150620015689050565b60008160405160200162000dac9190620025e5565b606060405180602001620016219062001fe9565b601f1982820381018352601f90910116604052905090565b600062000d2f83833062001c26565b600062000cce828263ffffffff62001c8016565b600062000d2f836010602085020163ffffffff62001c9d16565b60008151600114801562000d2f5750826001600160a01b0316826000815181106200169d57fe5b60200260200101516001600160a01b031614905092915050565b60006001600160e01b031984166308c077a560e11b141562001717576000620016e28460006200165c565b9050620016f0818462001676565b80156200170e57506200170c866001600160a01b031662001cc1565b155b91505062001731565b60405162461bcd60e51b8152600401620002e190620028e3565b949350505050565b600080620017536001845162001ccd90919063ffffffff16565b9050600062001769848363ffffffff62001cf816565b60ff1660048111156200177857fe5b90506060620017908560008563ffffffff62001d1516565b90506004826004811115620017a157fe5b1415620017c057620017b587878362001d9a565b935050505062000d2f565b6002826004811115620017cf57fe5b14156200180157856001600160a01b0316620017ec888362001ebd565b6001600160a01b031614935050505062000d2f565b60038260048111156200181057fe5b141562001870576000876040516020016200182c9190620025b4565b604051602081830303815290604052805190602001209050866001600160a01b03166200185a828462001ebd565b6001600160a01b03161494505050505062000d2f565b6000935050505062000d2f565b6000826200188e5750600162000d2f565b6000620018a4856001600160a01b031662001fa0565b9050806001600160a01b0316848490604051620018c19062001fa0565b600060405180830381858888f193505050503d806000811462001901576040519150601f19603f3d011682016040523d82523d6000602084013e62001906565b606091505b50909695505050505050565b60008111801562001936575060006200192a62001fa3565b6001600160a01b031614155b15620010d05760025460408051632630c12f60e01b815290516000926001600160a01b031691632630c12f916004808301926020929190829003018186803b1580156200198257600080fd5b505afa15801562001997573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019bd9190620021d9565b6001600160a01b031663f182178384846040518363ffffffff1660e01b8152600401620019ec9291906200278d565b60206040518083038186803b15801562001a0557600080fd5b505afa15801562001a1a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a409190620024c3565b905062001a4c62001fa3565b6001600160a01b031663c976bd9a85836040518363ffffffff1660e01b815260040162001a7b9291906200278d565b600060405180830381600087803b15801562001a9657600080fd5b505af115801562001aab573d6000803e3d6000fd5b5050505050505050565b604051631c48add360e21b81526060906001600160a01b03861690637122b74c9062001aed9060019088908890889060040162002c38565b600060405180830381600087803b15801562001b0857600080fd5b505af115801562001b1d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001b47919081019062002350565b95945050505050565b6000606063a9059cbb60e01b848460405160240162001b719291906200278d565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091529050606062001bb6878760008562001ab5565b80519091501562001bdf578080602001905181019062001bd791906200232e565b925062001be4565b600192505b5050949350505050565b600080838351602085016000f590506001600160a01b03811662000d2f5760405162461bcd60e51b8152600401620002e19062002b3f565b8151602080840191909120604051600092839162001c55916001600160f81b03199187918a9187910162002534565b60408051808303601f1901815291905280516020909101206001600160a01b03169695505050505050565b6000816004018351101562001c9457600080fd5b50016020015190565b6000816014018351101562001cb157600080fd5b500160200151600160601b900490565b3b63ffffffff16151590565b60008282111562001cf25760405162461bcd60e51b8152600401620002e190620029ec565b50900390565b6000816001018351101562001d0c57600080fd5b50016001015190565b60608183018451101562001d2857600080fd5b60608215801562001d455760405191506020820160405262001d91565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101562001d8057805183526020928301920162001d66565b5050858452601f01601f1916604052505b50949350505050565b600060606320c13b0b60e01b8560405160200162001db99190620027ea565b60408051601f198184030181529082905262001dda91869060240162002896565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050905060006060856001600160a01b03168360405162001e2d91906200256d565b600060405180830381855afa9150503d806000811462001e6a576040519150601f19603f3d011682016040523d82523d6000602084013e62001e6f565b606091505b509150915081801562001e83575080516020145b801562001eb257506320c13b0b60e01b62001ea682600063ffffffff62001c8016565b6001600160e01b031916145b979650505050505050565b6000815160411462001ed25750600062000cce565b60208201516040830151604184015160ff167f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111562001f1a576000935050505062000cce565b8060ff16601b148062001f3057508060ff16601c145b1562001f93576001868285856040516000815260200160405260405162001f5b949392919062002855565b6020604051602081039080840390855afa15801562001f7e573d6000803e3d6000fd5b50505060206040510351935050505062000cce565b6000935050505062000cce565b90565b600090565b6040518060a0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b6105bf8062002e2e83390190565b60008083601f84011262002009578182fd5b50813567ffffffffffffffff81111562002021578182fd5b60208301915083602080830285010111156200203c57600080fd5b9250929050565b600082601f83011262002054578081fd5b81356200206b620020658262002c9c565b62002c74565b8181529150602080830190848101818402860182018710156200208d57600080fd5b60005b84811015620020b9578135620020a68162002d11565b8452928201929082019060010162002090565b505050505092915050565b600082601f830112620020d5578081fd5b8135620020e6620020658262002c9c565b818152915060208083019084810160005b84811015620020b95762002111888484358a010162002167565b84529282019290820190600101620020f7565b60008083601f84011262002136578182fd5b50813567ffffffffffffffff8111156200214e578182fd5b6020830191508360208285010111156200203c57600080fd5b600082601f83011262002178578081fd5b813562002189620020658262002cbd565b9150808252836020828501011115620021a157600080fd5b8060208401602084013760009082016020015292915050565b600060208284031215620021cc578081fd5b813562000d2f8162002d11565b600060208284031215620021eb578081fd5b815162000d2f8162002d11565b600080604083850312156200220b578081fd5b8235620022188162002d11565b915060208301356200222a8162002d11565b809150509250929050565b60008060008060008060006080888a03121562002250578283fd5b87356200225d8162002d11565b9650602088013567ffffffffffffffff808211156200227a578485fd5b620022888b838c0162002124565b909850965060408a0135915080821115620022a1578485fd5b620022af8b838c0162002124565b909650945060608a0135915080821115620022c8578384fd5b50620022d78a828b0162001ff7565b989b979a50959850939692959293505050565b60008060208385031215620022fd578182fd5b823567ffffffffffffffff81111562002314578283fd5b620023228582860162001ff7565b90969095509350505050565b60006020828403121562002340578081fd5b8151801515811462000d2f578182fd5b60006020828403121562002362578081fd5b815167ffffffffffffffff81111562002379578182fd5b80830184601f8201126200238b578283fd5b805191506200239e620020658362002cbd565b828152856020848401011115620023b3578384fd5b62001b4783602083016020850162002ce2565b6000806000806000806101408789031215620023e0578182fd5b863567ffffffffffffffff80821115620023f8578384fd5b620024068a838b0162002167565b9750602091508189013596506040890135955089607f8a011262002428578384fd5b6200243460a062002c74565b8060608b016101008c018d8111156200244b578788fd5b875b60058110156200246c578235855293860193918601916001016200244d565b5091975050359250508082111562002482578384fd5b620024908a838b01620020c4565b9350610120890135915080821115620024a7578283fd5b50620024b689828a0162002043565b9150509295509295509295565b600060208284031215620024d5578081fd5b5051919050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526200252081602086016020860162002ce2565b601f01601f19169290920160200192915050565b6001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b600082516200258181846020870162002ce2565b9190910192915050565b600084516200259f81846020890162002ce2565b91909101928352506020820152604001919050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b6e2ba0a62622aa2fa1a922a0aa24a7a760891b815260609190911b6bffffffffffffffffffffffff1916600f82015260230190565b7f4d6574615472616e73616374696f6e28616464726573732077616c6c65742c6181527f646472657373206d6f64756c652c75696e743235362076616c75652c6279746560208201527f7320646174612c75696e74323536206e6f6e63652c75696e743235362076616c60408201527f6964556e74696c2c6164647265737320676173546f6b656e2c75696e7432353660608201527f2067617350726963652c75696e74323536206761734c696d69742c75696e743260808201527f3536206761734f766572686561642c616464726573732066656552656369706960a082015263656e742960e01b60c082015260c40190565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b6001600160a01b03861681526060602082018190526000906200276c9083018688620024dc565b828103604084015262002781818587620024dc565b98975050505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015620019065783516001600160e01b03191683529284019291840191600101620027c2565b90815260200190565b9b8c526001600160a01b039a8b1660208d0152988a1660408c015260608b019790975260808a019590955260a089019390935260c0880191909152851660e0870152610100860152610120850152610140840152166101608201526101800190565b93845260ff9290921660208401526040830152606082015260800190565b6001600160e01b03199290921682526001600160a01b0316602082015260400190565b600060408252620028ab604083018562002506565b828103602084015262001b47818562002506565b6020808252600a90820152695245454e5452414e435960b01b604082015260600190565b6020808252600e908201526d1253959053125117d351551213d160921b604082015260600190565b60208082526018908201527f4e4f545f46524f4d5f4d45544154585f4f525f4f574e45520000000000000000604082015260600190565b6020808252601190820152701253959053125117d1d054d7d312535255607a1b604082015260600190565b6020808252601290820152714241445f5349474e41545552455f4441544160701b604082015260600190565b60208082526010908201526f5452414e534645525f4641494c55524560801b604082015260600190565b6020808252600f908201526e1393d390d157d513d3d7d4d3505313608a1b604082015260600190565b6020808252600d908201526c5355425f554e444552464c4f5760981b604082015260600190565b60208082526015908201527424a72b20a624a22fa9a4a3a722a929afa7a92222a960591b604082015260600190565b6020808252600f908201526e4e4f4e43455f544f4f5f4c4152474560881b604082015260600190565b6020808252600f908201526e1514905394d1915497d19052531151608a1b604082015260600190565b6020808252601f908201527f4e4f545f46524f4d5f4d45544154585f4f525f57414c4c45545f4f574e455200604082015260600190565b60208082526013908201527213515510551617d5539055551213d492569151606a1b604082015260600190565b6020808252600c908201526b4144445f4f564552464c4f5760a01b604082015260600190565b6020808252600790820152661156141254915160ca1b604082015260600190565b6020808252600e908201526d10d4915055114c97d1905253115160921b604082015260600190565b60208082526010908201526f494e53554646494349454e545f47415360801b604082015260600190565b6020808252600c908201526b0929cac82989288be9082a6960a31b604082015260600190565b602080825260129082015271494e56414c49445f5349474e41545552455360701b604082015260600190565b6020808252600c908201526b4d554c5f4f564552464c4f5760a01b604082015260600190565b6000868252856020830152846040830152831515606083015260a0608083015262001eb260a083018462002506565b600060ff8616825260018060a01b03851660208301528360408301526080606083015262002c6a608083018462002506565b9695505050505050565b60405181810167ffffffffffffffff8111828210171562002c9457600080fd5b604052919050565b600067ffffffffffffffff82111562002cb3578081fd5b5060209081020190565b600067ffffffffffffffff82111562002cd4578081fd5b50601f01601f191660200190565b60005b8381101562002cff57818101518382015260200162002ce5565b83811115620012ec5750506000910152565b6001600160a01b038116811462002d2757600080fd5b50565b604051600090469062002d3d9062002d97565b604051809103902083600001518051906020012084602001518051906020012083866040015160405160200162002d7995949392919062002e01565b60405160208183030381529060405280519060200120915050919050565b7f454950373132446f6d61696e28737472696e67206e616d652c737472696e672081527f76657273696f6e2c75696e7432353620636861696e49642c6164647265737320602082015271766572696679696e67436f6e74726163742960701b604082015260520190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a0019056fe608060405234801561001057600080fd5b50610023336001600160e01b0361002816565b61006f565b600060405161003690610046565b6040519081900390209190915550565b7f6f72672e7a657070656c696e6f732e70726f78792e6f776e65720000000000008152601a0190565b6105418061007e6000396000f3fe60806040526004361061004a5760003560e01c8063025313a21461008e5780633659cfe6146100b95780634f1ef286146100db5780635c60da1b146100ee578063f1739cae14610103575b6000610054610123565b90506001600160a01b03811661006957600080fd5b60405136600082376000803683855af43d806000843e81801561008a578184f35b8184fd5b34801561009a57600080fd5b506100a3610142565b6040516100b091906104aa565b60405180910390f35b3480156100c557600080fd5b506100d96100d4366004610339565b610151565b005b6100d96100e9366004610367565b610182565b3480156100fa57600080fd5b506100a3610123565b34801561010f57600080fd5b506100d961011e366004610339565b610220565b60008060405161013290610475565b6040519081900390205492915050565b6000806040516101329061044c565b610159610142565b6001600160a01b0316336001600160a01b03161461017657600080fd5b61017f816102a1565b50565b61018a610142565b6001600160a01b0316336001600160a01b0316146101a757600080fd5b6101b082610151565b6000306001600160a01b031634836040516101cb9190610413565b60006040518083038185875af1925050503d8060008114610208576040519150601f19603f3d011682016040523d82523d6000602084013e61020d565b606091505b505090508061021b57600080fd5b505050565b610228610142565b6001600160a01b0316336001600160a01b03161461024557600080fd5b6001600160a01b03811661025857600080fd5b7f5a3e66efaa1e445ebd894728a69d6959842ea1e97bd79b892797106e270efcd9610281610142565b826040516102909291906104be565b60405180910390a161017f8161030d565b60006102ab610123565b9050816001600160a01b0316816001600160a01b031614156102cc57600080fd5b6102d58261032b565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b600060405161031b9061044c565b6040519081900390209190915550565b600060405161031b90610475565b60006020828403121561034a578081fd5b81356001600160a01b0381168114610360578182fd5b9392505050565b60008060408385031215610379578081fd5b82356001600160a01b038116811461038f578182fd5b9150602083013567ffffffffffffffff808211156103ab578283fd5b81850186601f8201126103bc578384fd5b80359250818311156103cc578384fd5b6103df601f8401601f19166020016104d8565b91508282528660208483010111156103f5578384fd5b6104068360208401602084016104ff565b5080925050509250929050565b60008251815b818110156104335760208186018101518583015201610419565b818111156104415782828501525b509190910192915050565b7f6f72672e7a657070656c696e6f732e70726f78792e6f776e65720000000000008152601a0190565b7f6f72672e7a657070656c696e6f732e70726f78792e696d706c656d656e74617481526234b7b760e91b602082015260230190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60405181810167ffffffffffffffff811182821017156104f757600080fd5b604052919050565b8281833750600091015256fea2646970667358221220f2866cb180971be35ca8efcd1e48412813a6a7fd09f1cddee17992e9561cd86564736f6c63430006060033a2646970667358221220e5cf4d06dbb43edb1435fbb84965911afd31aa0ea79ecf5ebd75e619b44f067564736f6c63430006060033
Verified Source Code Partial Match
Compiler: v0.6.6+commit.6c089d02
EVM: istanbul
Optimization: Yes (200 runs)
WalletFactoryModule.sol 4629 lines
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6.6;
pragma experimental ABIEncoderV2;
/**
* ENS Registry interface.
*/
interface ENSRegistry {
// Logged when the owner of a node assigns a new owner to a subnode.
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
// Logged when the owner of a node transfers ownership to a new account.
event Transfer(bytes32 indexed node, address owner);
// Logged when the resolver for a node changes.
event NewResolver(bytes32 indexed node, address resolver);
// Logged when the TTL of a node changes
event NewTTL(bytes32 indexed node, uint64 ttl);
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external;
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
}
/**
* ENS Resolver interface.
*/
abstract contract ENSResolver {
function addr(bytes32 _node) public view virtual returns (address);
function setAddr(bytes32 _node, address _addr) public virtual;
function name(bytes32 _node) public view virtual returns (string memory);
function setName(bytes32 _node, string memory _name) public virtual;
}
/**
* ENS Reverse Registrar interface.
*/
abstract contract ENSReverseRegistrar {
function claim(address _owner) public virtual returns (bytes32 _node);
function claimWithResolver(address _owner, address _resolver) public virtual returns (bytes32);
function setName(string memory _name) public virtual returns (bytes32);
function node(address _addr) public view virtual returns (bytes32);
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title Wallet
/// @dev Base contract for smart wallets.
/// Sub-contracts must NOT use non-default constructor to initialize
/// wallet states, instead, `init` shall be used. This is to enable
/// proxies to be deployed in front of the real wallet contract for
/// saving gas.
///
/// @author Daniel Wang - <[email protected]>
///
/// The design of this contract is inspired by Argent's contract codebase:
/// https://github.com/argentlabs/argent-contracts
interface Wallet
{
function owner() external view returns (address);
/// @dev Set a new owner.
function setOwner(address newOwner) external;
/// @dev Set up this wallet by assigning an original owner and a
/// list of initial modules. For each module, its `init` method
/// will be called with `address(this)` as the parameter.
///
/// Note that calling this method more than once will throw.
///
/// @param _controller The Controller instance.
/// @param _owner The owner of this wallet, must not be address(0).
/// @param _boostrapModule The bootstrap module.
function setup(address _controller, address _owner, address _boostrapModule) external;
/// @dev Adds a new module. The `init` method of the module
/// will be called with `address(this)` as the parameter.
/// This method must throw if the module has already been added.
/// @param _module The module's address.
function addModule(address _module) external;
/// @dev Removes an existing module. This method must throw if the module
/// has NOT been added or the module is the wallet's only module.
/// @param _module The module's address.
function removeModule(address _module) external;
/// @dev Checks if a module has been added to this wallet.
/// @param _module The module to check.
/// @return True if the module exists; False otherwise.
function hasModule(address _module) external view returns (bool);
/// @dev Binds a method from the given module to this
/// wallet so the method can be invoked using this wallet's default
/// function.
/// Note that this method must throw when the given module has
/// not been added to this wallet.
/// @param _method The method's 4-byte selector.
/// @param _module The module's address. Use address(0) to unbind the method.
function bindMethod(bytes4 _method, address _module) external;
/// @dev Returns the module the given method has been bound to.
/// @param _method The method's 4-byte selector.
/// @return _module The address of the bound module. If no binding exists,
/// returns address(0) instead.
function boundMethodModule(bytes4 _method) external view returns (address _module);
/// @dev Performs generic transactions. Any module that has been added to this
/// wallet can use this method to transact on any third-party contract with
/// msg.sender as this wallet itself.
///
/// This method will emit `Transacted` event if it doesn't throw.
///
/// Note: this method must ONLY allow invocations from a module that has
/// been added to this wallet. The wallet owner shall NOT be permitted
/// to call this method directly.
///
/// @param mode The transaction mode, 1 for CALL, 2 for DELEGATECALL.
/// @param to The desitination address.
/// @param value The amount of Ether to transfer.
/// @param data The data to send over using `to.call{value: value}(data)`
/// @return returnData The transaction's return value.
function transact(
uint8 mode,
address to,
uint value,
bytes calldata data
)
external
returns (bytes memory returnData);
}
// Taken from Argent's code base - https://github.com/argentlabs/argent-contracts/blob/develop/contracts/ens/ENSConsumer.sol
// with few modifications.
/**
* @title ENSConsumer
* @dev Helper contract to resolve ENS names.
* @author Julien Niset - <[email protected]>
*/
contract ENSConsumer {
using strings for *;
// namehash('addr.reverse')
bytes32 constant public ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
// the address of the ENS registry
address ensRegistry;
/**
* @dev No address should be provided when deploying on Mainnet to avoid storage cost. The
* contract will use the hardcoded value.
*/
constructor(address _ensRegistry) public {
ensRegistry = _ensRegistry;
}
/**
* @dev Resolves an ENS name to an address.
* @param _node The namehash of the ENS name.
*/
function resolveEns(bytes32 _node) public view returns (address) {
address resolver = getENSRegistry().resolver(_node);
return ENSResolver(resolver).addr(_node);
}
/**
* @dev Gets the official ENS registry.
*/
function getENSRegistry() public view returns (ENSRegistry) {
return ENSRegistry(ensRegistry);
}
/**
* @dev Gets the official ENS reverse registrar.
*/
function getENSReverseRegistrar() public view returns (ENSReverseRegistrar) {
return ENSReverseRegistrar(getENSRegistry().owner(ADDR_REVERSE_NODE));
}
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title Ownable
/// @author Brecht Devos - <[email protected]>
/// @dev The Ownable contract has an owner address, and provides basic
/// authorization control functions, this simplifies the implementation of
/// "user permissions".
contract Ownable
{
address public owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/// @dev The Ownable constructor sets the original `owner` of the contract
/// to the sender.
constructor()
public
{
owner = msg.sender;
}
/// @dev Throws if called by any account other than the owner.
modifier onlyOwner()
{
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
/// @dev Allows the current owner to transfer control of the contract to a
/// new owner.
/// @param newOwner The address to transfer ownership to.
function transferOwnership(
address newOwner
)
public
virtual
onlyOwner
{
require(newOwner != address(0), "ZERO_ADDRESS");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
function renounceOwnership()
public
onlyOwner
{
emit OwnershipTransferred(owner, address(0));
owner = address(0);
}
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title ReentrancyGuard
/// @author Brecht Devos - <[email protected]>
/// @dev Exposes a modifier that guards a function against reentrancy
/// Changing the value of the same storage value multiple times in a transaction
/// is cheap (starting from Istanbul) so there is no need to minimize
/// the number of times the value is changed
contract ReentrancyGuard
{
//The default value must be 0 in order to work behind a proxy.
uint private _guardValue;
modifier nonReentrant()
{
require(_guardValue == 0, "REENTRANCY");
_guardValue = 1;
_;
_guardValue = 0;
}
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title AddressSet
/// @author Daniel Wang - <[email protected]>
contract AddressSet
{
struct Set
{
address[] addresses;
mapping (address => uint) positions;
uint count;
}
mapping (bytes32 => Set) private sets;
function addAddressToSet(
bytes32 key,
address addr,
bool maintainList
) internal
{
Set storage set = sets[key];
require(set.positions[addr] == 0, "ALREADY_IN_SET");
if (maintainList) {
require(set.addresses.length == set.count, "PREVIOUSLY_NOT_MAINTAILED");
set.addresses.push(addr);
} else {
require(set.addresses.length == 0, "MUST_MAINTAIN");
}
set.count += 1;
set.positions[addr] = set.count;
}
function removeAddressFromSet(
bytes32 key,
address addr
)
internal
{
Set storage set = sets[key];
uint pos = set.positions[addr];
require(pos != 0, "NOT_IN_SET");
delete set.positions[addr];
set.count -= 1;
if (set.addresses.length > 0) {
address lastAddr = set.addresses[set.count];
if (lastAddr != addr) {
set.addresses[pos - 1] = lastAddr;
set.positions[lastAddr] = pos;
}
set.addresses.pop();
}
}
function removeSet(bytes32 key)
internal
{
delete sets[key];
}
function isAddressInSet(
bytes32 key,
address addr
)
internal
view
returns (bool)
{
return sets[key].positions[addr] != 0;
}
function numAddressesInSet(bytes32 key)
internal
view
returns (uint)
{
Set storage set = sets[key];
return set.count;
}
function addressesInSet(bytes32 key)
internal
view
returns (address[] memory)
{
Set storage set = sets[key];
require(set.count == set.addresses.length, "NOT_MAINTAINED");
return sets[key].addresses;
}
}/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title ERC20 Token Interface
/// @dev see https://github.com/ethereum/EIPs/issues/20
/// @author Daniel Wang - <[email protected]>
abstract contract ERC20
{
function totalSupply()
public
view
virtual
returns (uint);
function balanceOf(
address who
)
public
view
virtual
returns (uint);
function allowance(
address owner,
address spender
)
public
view
virtual
returns (uint);
function transfer(
address to,
uint value
)
public
virtual
returns (bool);
function transferFrom(
address from,
address to,
uint value
)
public
virtual
returns (bool);
function approve(
address spender,
uint value
)
public
virtual
returns (bool);
}
// Copied from https://eips.ethereum.org/EIPS/eip-1271.
abstract contract ERC1271 {
// bytes4(keccak256("isValidSignature(bytes,bytes)")
bytes4 constant internal MAGICVALUE = 0x20c13b0b;
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param _data Arbitrary length data signed on the behalf of address(this)
* @param _signature Signature byte array associated with _data
*
* MUST return the bytes4 magic value 0x20c13b0b when function passes.
* MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)
* MUST allow external calls
*/
function isValidSignature(
bytes memory _data,
bytes memory _signature)
public
view
virtual
returns (bytes4 magicValue);
}//Mainly taken from https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol
library BytesUtil {
function concat(
bytes memory _preBytes,
bytes memory _postBytes
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
assembly {
// Read the first 32 bytes of _preBytes storage, which is the length
// of the array. (We don't need to use the offset into the slot
// because arrays use the entire slot.)
let fslot := sload(_preBytes_slot)
// Arrays of 31 bytes or less have an even value in their slot,
// while longer arrays have an odd value. The actual length is
// the slot divided by two for odd values, and the lowest order
// byte divided by two for even values.
// If the slot is even, bitwise and the slot with 255 and divide by
// two to get the length. If the slot is odd, bitwise and the slot
// with -1 and divide by two.
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
let newlength := add(slength, mlength)
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
switch add(lt(slength, 32), lt(newlength, 32))
case 2 {
// Since the new array still fits in the slot, we just need to
// update the contents of the slot.
// uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
sstore(
_preBytes_slot,
// all the modifications to the slot are inside this
// next block
add(
// we can just add to the slot contents because the
// bytes we want to change are the LSBs
fslot,
add(
mul(
div(
// load the bytes from memory
mload(add(_postBytes, 0x20)),
// zero all bytes to the right
exp(0x100, sub(32, mlength))
),
// and now shift left the number of bytes to
// leave space for the length in the slot
exp(0x100, sub(32, newlength))
),
// increase length by the double of the memory
// bytes length
mul(mlength, 2)
)
)
)
}
case 1 {
// The stored value fits in the slot, but the combined value
// will exceed it.
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes_slot)
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes_slot, add(mul(newlength, 2), 1))
// The contents of the _postBytes array start 32 bytes into
// the structure. Our first read should obtain the `submod`
// bytes that can fit into the unused space in the last word
// of the stored array. To get this, we read 32 bytes starting
// from `submod`, so the data we read overlaps with the array
// contents by `submod` bytes. Masking the lowest-order
// `submod` bytes allows us to add that value directly to the
// stored value.
let submod := sub(32, slength)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(
sc,
add(
and(
fslot,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
),
and(mload(mc), mask)
)
)
for {
mc := add(mc, 0x20)
sc := add(sc, 1)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
default {
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes_slot)
// Start copying to the last used word of the stored array.
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes_slot, add(mul(newlength, 2), 1))
// Copy over the first `submod` bytes of the new data as in
// case 1 above.
let slengthmod := mod(slength, 32)
let mlengthmod := mod(mlength, 32)
let submod := sub(32, slengthmod)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(sc, add(sload(sc), and(mload(mc), mask)))
for {
sc := add(sc, 1)
mc := add(mc, 0x20)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
}
}
function slice(
bytes memory _bytes,
uint _start,
uint _length
)
internal
pure
returns (bytes memory)
{
require(_bytes.length >= (_start + _length));
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) {
require(_bytes.length >= (_start + 20));
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) {
require(_bytes.length >= (_start + 1));
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) {
require(_bytes.length >= (_start + 2));
uint16 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x2), _start))
}
return tempUint;
}
function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) {
require(_bytes.length >= (_start + 4));
uint32 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x4), _start))
}
return tempUint;
}
function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) {
require(_bytes.length >= (_start + 8));
uint64 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x8), _start))
}
return tempUint;
}
function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) {
require(_bytes.length >= (_start + 12));
uint96 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xc), _start))
}
return tempUint;
}
function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) {
require(_bytes.length >= (_start + 16));
uint128 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x10), _start))
}
return tempUint;
}
function toUint(bytes memory _bytes, uint _start) internal pure returns (uint256) {
require(_bytes.length >= (_start + 32));
uint256 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
function toBytes4(bytes memory _bytes, uint _start) internal pure returns (bytes4) {
require(_bytes.length >= (_start + 4));
bytes4 tempBytes4;
assembly {
tempBytes4 := mload(add(add(_bytes, 0x20), _start))
}
return tempBytes4;
}
function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) {
require(_bytes.length >= (_start + 32));
bytes32 tempBytes32;
assembly {
tempBytes32 := mload(add(add(_bytes, 0x20), _start))
}
return tempBytes32;
}
function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
bool success = true;
assembly {
let length := mload(_preBytes)
// if lengths don't match the arrays are not equal
switch eq(length, mload(_postBytes))
case 1 {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
let mc := add(_preBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
// the next line is the loop condition:
// while(uint(mc < end) + cb == 2)
} eq(add(lt(mc, end), cb), 2) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// if any of these checks fails then arrays are not equal
if iszero(eq(mload(mc), mload(cc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
function equalStorage(
bytes storage _preBytes,
bytes memory _postBytes
)
internal
view
returns (bool)
{
bool success = true;
assembly {
// we know _preBytes_offset is 0
let fslot := sload(_preBytes_slot)
// Decode the length of the stored array like in concatStorage().
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
// if lengths don't match the arrays are not equal
switch eq(slength, mlength)
case 1 {
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
if iszero(iszero(slength)) {
switch lt(slength, 32)
case 1 {
// blank the last byte which is the length
fslot := mul(div(fslot, 0x100), 0x100)
if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
// unsuccess:
success := 0
}
}
default {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes_slot)
let sc := keccak256(0x0, 0x20)
let mc := add(_postBytes, 0x20)
let end := add(mc, mlength)
// the next line is the loop condition:
// while(uint(mc < end) + cb == 2)
for {} eq(add(lt(mc, end), cb), 2) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
if iszero(eq(sload(sc), mload(mc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title Utility Functions for uint
/// @author Daniel Wang - <[email protected]>
library MathUint
{
function mul(
uint a,
uint b
)
internal
pure
returns (uint c)
{
c = a * b;
require(a == 0 || c / a == b, "MUL_OVERFLOW");
}
function sub(
uint a,
uint b
)
internal
pure
returns (uint)
{
require(b <= a, "SUB_UNDERFLOW");
return a - b;
}
function add(
uint a,
uint b
)
internal
pure
returns (uint c)
{
c = a + b;
require(c >= a, "ADD_OVERFLOW");
}
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title Utility Functions for addresses
/// @author Daniel Wang - <[email protected]>
/// @author Brecht Devos - <[email protected]>
library AddressUtil
{
using AddressUtil for *;
function isContract(
address addr
)
internal
view
returns (bool)
{
uint32 size;
assembly { size := extcodesize(addr) }
return (size > 0);
}
function toPayable(
address addr
)
internal
pure
returns (address payable)
{
return address(uint160(addr));
}
// Works like address.send but with a customizable gas limit
// Make sure your code is safe for reentrancy when using this function!
function sendETH(
address to,
uint amount,
uint gasLimit
)
internal
returns (bool success)
{
if (amount == 0) {
return true;
}
address payable recipient = to.toPayable();
/* solium-disable-next-line */
(success, ) = recipient.call{value: amount, gas: gasLimit}("");
}
// Works like address.transfer but with a customizable gas limit
// Make sure your code is safe for reentrancy when using this function!
function sendETHAndVerify(
address to,
uint amount,
uint gasLimit
)
internal
returns (bool success)
{
success = to.sendETH(amount, gasLimit);
require(success, "TRANSFER_FAILURE");
}
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title DataStore
/// @dev Modules share states by accessing the same storage instance.
/// Using ModuleStorage will achieve better module decoupling.
///
/// @author Daniel Wang - <[email protected]>
///
/// The design of this contract is inspired by Argent's contract codebase:
/// https://github.com/argentlabs/argent-contracts
contract DataStore
{
modifier onlyWalletModule(address wallet)
{
require(Wallet(wallet).hasModule(msg.sender), "UNAUTHORIZED");
_;
}
}/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title Claimable
/// @author Brecht Devos - <[email protected]>
/// @dev Extension for the Ownable contract, where the ownership needs
/// to be claimed. This allows the new owner to accept the transfer.
contract Claimable is Ownable
{
address public pendingOwner;
/// @dev Modifier throws if called by any account other than the pendingOwner.
modifier onlyPendingOwner() {
require(msg.sender == pendingOwner, "UNAUTHORIZED");
_;
}
/// @dev Allows the current owner to set the pendingOwner address.
/// @param newOwner The address to transfer ownership to.
function transferOwnership(
address newOwner
)
public
override
onlyOwner
{
require(newOwner != address(0) && newOwner != owner, "INVALID_ADDRESS");
pendingOwner = newOwner;
}
/// @dev Allows the pendingOwner address to finalize the transfer.
function claimOwnership()
public
onlyPendingOwner
{
emit OwnershipTransferred(owner, pendingOwner);
owner = pendingOwner;
pendingOwner = address(0);
}
}
contract OwnerManagable is Claimable, AddressSet
{
bytes32 internal constant MANAGER = keccak256("__MANAGED__");
event ManagerAdded (address indexed manager);
event ManagerRemoved(address indexed manager);
modifier onlyManager
{
require(isManager(msg.sender), "NOT_MANAGER");
_;
}
modifier onlyOwnerOrManager
{
require(msg.sender == owner || isManager(msg.sender), "NOT_OWNER_OR_MANAGER");
_;
}
constructor() public Claimable() {}
/// @dev Gets the managers.
/// @return The list of managers.
function managers()
public
view
returns (address[] memory)
{
return addressesInSet(MANAGER);
}
/// @dev Gets the number of managers.
/// @return The numer of managers.
function numManagers()
public
view
returns (uint)
{
return numAddressesInSet(MANAGER);
}
/// @dev Checks if an address is a manger.
/// @param addr The address to check.
/// @return True if the address is a manager, False otherwise.
function isManager(address addr)
public
view
returns (bool)
{
return isAddressInSet(MANAGER, addr);
}
/// @dev Adds a new manager.
/// @param manager The new address to add.
function addManager(address manager)
public
onlyOwner
{
addManagerInternal(manager);
}
/// @dev Removes a manager.
/// @param manager The manager to remove.
function removeManager(address manager)
public
onlyOwner
{
removeAddressFromSet(MANAGER, manager);
emit ManagerRemoved(manager);
}
function addManagerInternal(address manager)
internal
{
addAddressToSet(MANAGER, manager, true);
emit ManagerAdded(manager);
}
}/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title ModuleRegistry
/// @dev A registry for modules.
///
/// @author Daniel Wang - <[email protected]>
interface ModuleRegistry
{
function registerModule(address module) external;
function deregisterModule(address module) external;
function isModuleRegistered(address module) external view returns (bool);
function modules() external view returns (address[] memory _modules);
function numOfModules() external view returns (uint);
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title WalletRegistry
/// @dev A registry for wallets.
/// @author Daniel Wang - <[email protected]>
interface WalletRegistry
{
function registerWallet(address wallet) external;
function isWalletRegistered(address addr) external view returns (bool);
function numOfWallets() external view returns (uint);
}
/*
Copyright 2017 Loopring Project Ltd (Loopring Foundation).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/// @title QuotaStore
/// @dev This store maintains daily spending quota for each wallet.
/// A rolling daily limit is used.
contract QuotaStore is DataStore
{
using MathUint for uint;
uint public defaultQuota;
struct Quota
{
uint currentQuota; // 0 indicates default
uint pendingQuota;
uint64 pendingUntil;
uint64 spentTimestamp;
uint spentAmount;
}
mapping (address => Quota) public quotas;
event QuotaScheduled(
address indexed wallet,
uint pendingQuota,
uint64 pendingUntil
);
constructor(uint _defaultQuota)
public
DataStore()
{
defaultQuota = _defaultQuota;
}
function changeQuota(
address wallet,
uint newQuota,
uint effectiveTime
)
public
onlyWalletModule(wallet)
{
quotas[wallet].currentQuota = currentQuota(wallet);
...
// [truncated — 148428 bytes total]
Read Contract
DOMAIN_SEPARATOR 0x3644e515 → bytes32
METATRANSACTION_TYPEHASH 0x2d621c51 → bytes32
bindableMethods 0xafa3363d → bytes4[]
computeWalletAddress 0xfddf851f → address
controller 0xf77c4791 → address
lastNonce 0xc0fd43b4 → uint256
walletImplementation 0x8117abc1 → address
wallets 0x89b08f11 → uint256
Write Contract 6 functions
These functions modify contract state and require a wallet transaction to execute.
activate 0x0f15f4c0
No parameters
addModule 0x5a1db8c4
address wallet
address module
collectTokens 0x90502c2e
address[] tokens
createWallet 0x1180ef4a
address _owner
string _label
bytes _labelApproval
address[] _modules
returns: address
deactivate 0x51b42b00
No parameters
executeMetaTx 0x0ab9ad33
bytes data
uint256 nonce
uint256 validUntil
uint256[5] gasSetting
bytes[] signatures
address[] signers
Recent Transactions
This address has 45 on-chain transactions, but only 0.8% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →