Address Contract Partially Verified
Address
0x6F400810b62df8E13fded51bE75fF5393eaa841F
Balance
0 ETH
Nonce
1
Code Size
23307 bytes
Creator
0x2e173510...b654 at tx 0xe74e8e96...0ac36a
Indexed Transactions
0
Contract Bytecode
23307 bytes
0x608060405234801561001057600080fd5b50600436106102535760003560e01c806395466a4611610146578063e1d5f64e116100c3578063f36b635511610087578063f36b635514611217578063f3f479821461124f578063f47c84c51461127d578063f940e38514611285578063fb736d32146112b3578063ff97c626146112bb57610253565b8063e1d5f64e146111a1578063e48c015e146111a9578063e720ac8e146111b1578063ed2da357146111b9578063ef574d23146111f157610253565b8063c33eb9f61161010a578063c33eb9f6146110f4578063c49598fb14611122578063d48bfca714611145578063d4fac45d1461116b578063d73792a91461119957610253565b806395466a4614610c4c5780639bb0f59914610c845780639cc84ed314610cbe578063b3c0afa114610cfb578063c1ef283814610d4757610253565b80634bdc1b4c116101d457806372f3dd391161019857806372f3dd3914610b38578063793b8c6d14610b5e5780637fb47b0614610bde5780638e499bcf14610be6578063907767c014610c0557610253565b80634bdc1b4c146106cf57806361ed16d014610770578063647846a51461079457806365cc3e781461079c57806366367c1014610b1757610253565b80632f10d0821161021b5780632f10d08214610600578063397a1b281461063d57806341e383ed1461066b57806343383ac31461067357806347e7ef24146106a357610253565b8063094c7e191461025857806317569c1d1461027257806323d4a3c91461027a57806326c3d394146102f75780632e4c83bd14610345575b600080fd5b6102606112c3565b60408051918252519081900360200190f35b6102606112c8565b6102826112d5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102bc5781810151838201526020016102a4565b50505050905090810190601f1680156102e95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610260600480360360a081101561030d57600080fd5b5061ffff813581169160208101359091169063ffffffff604082013516906001600160801b03606082013581169160800135166114be565b610260600480360360e081101561035b57600080fd5b63ffffffff82351691602081013591810190606081016040820135600160201b81111561038757600080fd5b82018360208201111561039957600080fd5b803590602001918460208302840111600160201b831117156103ba57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561040957600080fd5b82018360208201111561041b57600080fd5b803590602001918460208302840111600160201b8311171561043c57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561048b57600080fd5b82018360208201111561049d57600080fd5b803590602001918460208302840111600160201b831117156104be57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561050d57600080fd5b82018360208201111561051f57600080fd5b803590602001918460208302840111600160201b8311171561054057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561058f57600080fd5b8201836020820111156105a157600080fd5b803590602001918460208302840111600160201b831117156105c257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506114e3945050505050565b6106216004803603602081101561061657600080fd5b503561ffff16611f34565b604080516001600160a01b039092168252519081900360200190f35b6106696004803603604081101561065357600080fd5b506001600160a01b038135169060200135611fcb565b005b610260611fe1565b6102826004803603604081101561068957600080fd5b5080356001600160a01b0316906020013561ffff16611fed565b610669600480360360408110156106b957600080fd5b506001600160a01b038135169060200135612259565b610669600480360360208110156106e557600080fd5b810190602081018135600160201b8111156106ff57600080fd5b82018360208201111561071157600080fd5b803590602001918460208302840111600160201b8311171561073257600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061235a945050505050565b6107786125d9565b604080516001600160801b039092168252519081900360200190f35b6106216125df565b610ac7600480360360c08110156107b257600080fd5b810190602081018135600160201b8111156107cc57600080fd5b8201836020820111156107de57600080fd5b803590602001918460208302840111600160201b831117156107ff57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561084e57600080fd5b82018360208201111561086057600080fd5b803590602001918460208302840111600160201b8311171561088157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156108d057600080fd5b8201836020820111156108e257600080fd5b803590602001918460208302840111600160201b8311171561090357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561095257600080fd5b82018360208201111561096457600080fd5b803590602001918460208302840111600160201b8311171561098557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156109d457600080fd5b8201836020820111156109e657600080fd5b803590602001918460208302840111600160201b83111715610a0757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610a5657600080fd5b820183602082011115610a6857600080fd5b803590602001918460208302840111600160201b83111715610a8957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506125f4945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610b03578181015183820152602001610aeb565b505050509050019250505060405180910390f35b61077860048036036020811015610b2d57600080fd5b503561ffff166126e2565b61028260048036036020811015610b4e57600080fd5b50356001600160a01b03166126fd565b610b8a60048036036040811015610b7457600080fd5b506001600160a01b03813516906020013561270d565b6040805161ffff988916815296909716602087015263ffffffff948516868801529290931660608501526001600160801b03908116608085015291821660a08401521660c082015290519081900360e00190f35b61077861278b565b610bee612791565b6040805161ffff9092168252519081900360200190f35b610c3360048036036040811015610c1b57600080fd5b506001600160a01b038135811691602001351661279b565b6040805163ffffffff9092168252519081900360200190f35b61028260048036036060811015610c6257600080fd5b506001600160a01b038135169061ffff602082013581169160400135166127be565b610caa60048036036020811015610c9a57600080fd5b50356001600160a01b03166129d7565b604080519115158252519081900360200190f35b610cc6612a3f565b6040805163ffffffff90951685526001600160a01b039093166020850152838301919091526060830152519081900360800190f35b610d2960048036036040811015610d1157600080fd5b506001600160a01b0381358116916020013516612a63565b6040805192835263ffffffff90911660208301528051918290030190f35b610ac7600480360360e0811015610d5d57600080fd5b810190602081018135600160201b811115610d7757600080fd5b820183602082011115610d8957600080fd5b803590602001918460208302840111600160201b83111715610daa57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610df957600080fd5b820183602082011115610e0b57600080fd5b803590602001918460208302840111600160201b83111715610e2c57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610e7b57600080fd5b820183602082011115610e8d57600080fd5b803590602001918460208302840111600160201b83111715610eae57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610efd57600080fd5b820183602082011115610f0f57600080fd5b803590602001918460208302840111600160201b83111715610f3057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610f7f57600080fd5b820183602082011115610f9157600080fd5b803590602001918460208302840111600160201b83111715610fb257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561100157600080fd5b82018360208201111561101357600080fd5b803590602001918460208302840111600160201b8311171561103457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561108357600080fd5b82018360208201111561109557600080fd5b803590602001918460208302840111600160201b831117156110b657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612abd945050505050565b610d296004803603604081101561110a57600080fd5b506001600160a01b0381358116916020013516612ae2565b610caa6004803603602081101561113857600080fd5b503563ffffffff16612b3c565b6106696004803603602081101561115b57600080fd5b50356001600160a01b0316612b70565b6102606004803603604081101561118157600080fd5b506001600160a01b0381358116916020013516612dac565b610778612ed5565b610778612edb565b610c33612ee0565b610c33612ee6565b610282600480360360608110156111cf57600080fd5b506001600160a01b038135169061ffff60208201358116916040013516612eee565b610bee6004803603602081101561120757600080fd5b50356001600160a01b0316613064565b6106696004803603606081101561122d57600080fd5b5080356001600160a01b0316906020810135906040013563ffffffff166130cc565b610caa6004803603604081101561126557600080fd5b506001600160a01b03813581169160200135166131d6565b61026061324e565b6106696004803603604081101561129b57600080fd5b506001600160a01b0381358116916020013516613254565b610260613451565b610260613456565b606481565b61012c4281900690035b90565b60606000600c73cddb32b6bb2808d5b5115daab207479ce98d263663d58c862c90916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561132b57600080fd5b505af415801561133f573d6000803e3d6000fd5b505050506040513d602081101561135557600080fd5b505111156112d2576000600c73cddb32b6bb2808d5b5115daab207479ce98d26366368fb2bc290916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156113b157600080fd5b505af41580156113c5573d6000803e3d6000fd5b505050506040513d60208110156113db57600080fd5b5051905060005b806114b9576114006113f3836126fd565b849063ffffffff61348916565b600d549093506001600160a01b0383811691161415611421575060016114b4565b60408051600160e21b63218777b3028152600c60048201526001600160a01b0384166024820152905173cddb32b6bb2808d5b5115daab207479ce98d26369163861ddecc916044808301926020929190829003018186803b15801561148557600080fd5b505af4158015611499573d6000803e3d6000fd5b505050506040513d60208110156114af57600080fd5b505191505b6113e2565b505090565b60006114d586866114cd612ee6565b878787613506565b61ffff169695505050505050565b60006114ee88612b3c565b61152c57604051600160e51b62461bcd02815260040180806020018281038252602f815260200180615889602f913960400191505060405180910390fd5b61153587613a87565b61157357604051600160e51b62461bcd02815260040180806020018281038252603f8152602001806159e4603f913960400191505060405180910390fd5b61157c83613aba565b6115ba57604051600160e51b62461bcd02815260040180806020018281038252602c8152602001806158fd602c913960400191505060405180910390fd5b816000815181106115c757fe5b602002602001015161ffff166000141561162b5760408051600160e51b62461bcd02815260206004820152601a60248201527f46656520746f6b656e2068617320666978656420707269636521000000000000604482015290519081900360640190fd5b61163482613b11565b61167257604051600160e51b62461bcd02815260040180806020018281038252602181526020018061599d6021913960400191505060405180910390fd5b601e865111156116b657604051600160e51b62461bcd0281526004018080602001828103825260238152602001806157e36023913960400191505060405180910390fd5b60006116c0613b69565b90506116ca613bfe565b6116d48484613fcd565b6116e060076000615620565b60606116eb846140bb565b90506000805b8951811015611b5557611702615641565b600460008c848151811061171257fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000208a838151811061174657fe5b602002602001015161ffff168154811061175c57fe5b60009182526020918290206040805160e0810182526002909302909101805461ffff8082168552620100008204169484019490945263ffffffff600160201b8504811692840192909252600160401b840490911660608301526001600160801b03600160601b909304831660808301526001015480831660a0830152600160801b900490911660c082015290506117f3818e6140f2565b6118475760408051600160e51b62461bcd02815260206004820152601060248201527f4f7264657220697320696e76616c696400000000000000000000000000000000604482015290519081900360640190fd5b6000806118678b858151811061185957fe5b602002602001015184614125565b90925090506127106001600160801b03831610156118b957604051600160e51b62461bcd0281526004018080602001828103825260238152602001806157c06023913960400191505060405180910390fd5b6127106001600160801b038216101561190657604051600160e51b62461bcd028152600401808060200182810382526024815260200180615a4c6024913960400191505060405180910390fd5b825160208401516119219188918c868663ffffffff61417316565b806001600160801b031661193484614227565b6001600160801b0316101561197d57604051600160e51b62461bcd02815260040180806020018281038252603181526020018061594b6031913960400191505060405180910390fd5b60a083015161199e906001600160801b03848116911663ffffffff61423616565b60808401516119bf906001600160801b03848116911663ffffffff61423616565b1115611a155760408051600160e51b62461bcd02815260206004820152601960248201527f6c696d6974207072696365206e6f742073617469736669656400000000000000604482015290519081900360640190fd5b611a2f611a228385614292565b869063ffffffff6143c516565b9450611a628d8581518110611a4057fe5b60200260200101518d8681518110611a5457fe5b602002602001015183614422565b611a958d8581518110611a7157fe5b6020026020010151611a868560000151611f34565b846001600160801b03166145b9565b826020015161ffff168c8581518110611aaa57fe5b602002602001015161ffff168e8681518110611ac257fe5b60200260200101516001600160a01b03167fafa5bc1fb80950b7cb2353ba0cf16a6d68de75801f2dac54b2dae9268450010a86600001518587604051808461ffff1661ffff168152602001836001600160801b03166001600160801b03168152602001826001600160801b03166001600160801b03168152602001935050505060405180910390a45050506001016116f1565b5060005b8951811015611caf57611b6a615641565b600460008c8481518110611b7a57fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000208a8381518110611bae57fe5b602002602001015161ffff1681548110611bc457fe5b600091825260208083206040805160e0810182526002909402909101805461ffff8082168652620100008204169385019390935263ffffffff600160201b8404811692850192909252600160401b830490911660608401526001600160801b03600160601b909204821660808401526001015480821660a0840152600160801b90041660c08201528a51909250611c6f908b9085908110611c6157fe5b602002602001015183614125565b915050611ca58c8481518110611c8157fe5b6020026020010151611c968460200151611f34565b836001600160801b0316614619565b5050600101611b59565b506000805b8a51811015611dda57611dd0611dc3600460008e8581518110611cd357fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000208c8481518110611d0757fe5b602002602001015161ffff1681548110611d1d57fe5b60009182526020918290206040805160e0810182526002909302909101805461ffff8082168552620100008204169484019490945263ffffffff600160201b8504811692840192909252600160401b840490911660608301526001600160801b03600160601b909304831660808301526001015480831660a0830152600160801b900490911660c08201528d518e9085908110611db657fe5b6020026020010151614685565b839063ffffffff6143c516565b9150600101611cb4565b5060006002611de885614788565b81611def57fe5b0490506000611e1483611e08868563ffffffff6143c516565b9063ffffffff6147a616565b9050611e1f816147e8565b611e2882614834565b611e3185614850565b611e3e8e8d8d8d8c614925565b336001600160a01b03167f2140b6253bf38aea0a4ac9e9e6427b256e4035d60df4a85bb139ce975eb6b41d8585858a8e8e604051808781526020018681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015611ecb578181015183820152602001611eb3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015611f0a578181015183820152602001611ef2565b505050509050019850505050505050505060405180910390a29d9c50505050505050505050505050565b60408051600160e21b632ffeb2d7028152600e600482015261ffff83166024820152905160009173ed4d05496c71e71cc2a8726af1242c22108d17619163bffacb5c91604480820192602092909190829003018186803b158015611f9757600080fd5b505af4158015611fab573d6000803e3d6000fd5b505050506040513d6020811015611fc157600080fd5b505190505b919050565b611fdd8282611fd8612ee6565b6130cc565b5050565b678ac7230489e8000081565b6060600c73cddb32b6bb2808d5b5115daab207479ce98d263663d58c862c90916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561204157600080fd5b505af4158015612055573d6000803e3d6000fd5b505050506040513d602081101561206b57600080fd5b505161207657612253565b6000836001600160a01b03811661214d5760408051600160e11b63347d95e1028152600c6004820152905173cddb32b6bb2808d5b5115daab207479ce98d2636916368fb2bc2916024808301926020929190829003018186803b1580156120dc57600080fd5b505af41580156120f0573d6000803e3d6000fd5b505050506040513d602081101561210657600080fd5b5051604080516001600160a01b03831660601b602082015281518082036014018152603490910190915290915061214490849063ffffffff61348916565b92506001909101905b8361ffff168261ffff161080156121725750600d546001600160a01b03828116911614155b156122505760408051600160e21b63218777b3028152600c60048201526001600160a01b0383166024820152905173cddb32b6bb2808d5b5115daab207479ce98d26369163861ddecc916044808301926020929190829003018186803b1580156121db57600080fd5b505af41580156121ef573d6000803e3d6000fd5b505050506040513d602081101561220557600080fd5b5051604080516001600160a01b03831660601b602082015281518082036014018152603490910190915290915061224390849063ffffffff61348916565b925060019091019061214d565b50505b92915050565b6122633383614a75565b61226f82333084614b35565b336000908152602081815260408083206001600160a01b03861684529091529020600101546122a4908263ffffffff6143c516565b336000908152602081815260408083206001600160a01b03871684529091529020600101556122d1612ee6565b336000818152602081815260408083206001600160a01b0388168085529252909120600201805463ffffffff191663ffffffff94909416939093179092557fc11cc34e93c67a93382b99f2498e9937198798f3c1c2888008ffc0eeb82f68c483612339612ee6565b6040805192835263ffffffff90911660208301528051918290030190a35050565b60006001612366612ee6565b03905060005b82518161ffff1610156125d45733600090815260046020526040902083516124469190859061ffff851690811061239f57fe5b602002602001015161ffff16815481106123b557fe5b60009182526020918290206040805160e0810182526002909302909101805461ffff8082168552620100008204169484019490945263ffffffff600160201b8504811692840192909252600160401b840490911660608301526001600160801b03600160601b909304831660808301526001015480831660a0830152600160801b900490911660c0820152836140f2565b612502573360009081526004602052604090208351849061ffff841690811061246b57fe5b602002602001015161ffff168154811061248157fe5b60009182526020822060029091020180546001600160e01b031916815560010155825133907f7b0a9854603fbbe7606a58b70d113bd0d1ec8475f1b8cc9603c2d377e67835cd90859061ffff85169081106124d857fe5b6020026020010151604051808261ffff1661ffff16815260200191505060405180910390a26125cc565b3360009081526004602052604090208351839190859061ffff851690811061252657fe5b602002602001015161ffff168154811061253c57fe5b906000526020600020906002020160000160086101000a81548163ffffffff021916908363ffffffff160217905550336001600160a01b03167f7a02963a37046835196f1a3185a036fd67cfca72283e46e4b3cdb99939851937848361ffff16815181106125a657fe5b6020026020010151604051808261ffff1661ffff16815260200191505060405180910390a25b60010161236c565b505050565b61271081565b6003546201000090046001600160a01b031681565b60608651604051908082528060200260200182016040528015612621578160200160208202803883390190505b50905060005b87518110156126d7576126b088828151811061263f57fe5b602002602001015188838151811061265357fe5b602002602001015188848151811061266757fe5b602002602001015188858151811061267b57fe5b602002602001015188868151811061268f57fe5b60200260200101518887815181106126a357fe5b6020026020010151613506565b8282815181106126bc57fe5b61ffff90921660209283029190910190910152600101612627565b509695505050505050565b6005602052600090815260409020546001600160801b031681565b6060612253826000600019612eee565b6004602052816000526040600020818154811061272657fe5b60009182526020909120600290910201805460019091015461ffff808316945062010000830416925063ffffffff600160201b8304811692600160401b8104909116916001600160801b03600160601b90920482169181811691600160801b90041687565b60001981565b60035461ffff1681565b600160209081526000928352604080842090915290825290205463ffffffff1681565b6060600c73cddb32b6bb2808d5b5115daab207479ce98d263663d58c862c90916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561281257600080fd5b505af4158015612826573d6000803e3d6000fd5b505050506040513d602081101561283c57600080fd5b5051612847576129d0565b82846001600160a01b0381166128db5760408051600160e11b63347d95e1028152600c6004820152905173cddb32b6bb2808d5b5115daab207479ce98d2636916368fb2bc2916024808301926020929190829003018186803b1580156128ac57600080fd5b505af41580156128c0573d6000803e3d6000fd5b505050506040513d60208110156128d657600080fd5b505190505b825161ffff8516906070900410156129cd576129116113f3828460706001600160801b031687518161290957fe5b048803612eee565b600d549093506001600160a01b038281169116141561293257506129d09050565b60408051600160e21b63218777b3028152600c60048201526001600160a01b038316602482015290516000935073cddb32b6bb2808d5b5115daab207479ce98d26369163861ddecc916044808301926020929190829003018186803b15801561299a57600080fd5b505af41580156129ae573d6000803e3d6000fd5b505050506040513d60208110156129c457600080fd5b505190506128db565b50505b9392505050565b60408051600160e11b636e8930a3028152600e60048201526001600160a01b0383166024820152905160009173ed4d05496c71e71cc2a8726af1242c22108d17619163dd12614691604480820192602092909190829003018186803b158015611f9757600080fd5b600654600954600a54600b5463ffffffff909316926001600160a01b039092169184565b600080612a6e61567d565b5050506001600160a01b039182166000908152602081815260408083209390941682529182528290208251808401909352600181015480845260029091015463ffffffff169290910182905291565b6060612ac88861235a565b612ad68787878787876125f4565b98975050505050505050565b600080612aed61567d565b5050506001600160a01b039182166000908152602081815260408083209390941682529182528290208251808401909352600381015480845260049091015463ffffffff169290910182905291565b60006001612b48612ee6565b0363ffffffff168263ffffffff161480156122535750603c612b686112c8565b101592915050565b60025460035461ffff1610612bcf5760408051600160e51b62461bcd02815260206004820152601260248201527f4d617820746f6b656e7320726561636865640000000000000000000000000000604482015290519081900360640190fd5b60035461ffff1615612c565760035460408051600160e01b634417f4db028152336004820152678ac7230489e8000060248201529051620100009092046001600160a01b031691634417f4db9160448082019260009290919082900301818387803b158015612c3d57600080fd5b505af1158015612c51573d6000803e3d6000fd5b505050505b60035460408051600160e01b639f3cb655028152600e600482015261ffff90921660248301526001600160a01b03831660448301525173ed4d05496c71e71cc2a8726af1242c22108d176191639f3cb655916064808301926020929190829003018186803b158015612cc757600080fd5b505af4158015612cdb573d6000803e3d6000fd5b505050506040513d6020811015612cf157600080fd5b5051612d475760408051600160e51b62461bcd02815260206004820152601860248201527f546f6b656e20616c726561647920726567697374657265640000000000000000604482015290519081900360640190fd5b600354604080516001600160a01b038416815261ffff909216602083015280517fe4b282c4351ffe36572a572de193a7de086edc47c9e62669fe6ab49fc53a33139281900390910190a1506003805461ffff8082166001011661ffff19909116179055565b6001600160a01b03808316600090815260208181526040808320938516835292905290812054612dda612ee6565b6001600160a01b038086166000908152602081815260408083209388168352929052206002015463ffffffff91821691161015612e4c576001600160a01b0380851660009081526020818152604080832093871683529290522060010154612e4990829063ffffffff6143c516565b90505b612e54612ee6565b6001600160a01b038086166000908152602081815260408083209388168352929052206004015463ffffffff918216911610156129d0576001600160a01b0380851660009081526020818152604080832093871683529290522060030154612ecd90612ec09083614b98565b829063ffffffff6147a616565b949350505050565b6103e881565b607081565b61012c81565b61012c420490565b6060825b6001600160a01b038516600090815260046020526040902054612f1b9061ffff86860116614b98565b8161ffff16101561305c5761305261304586612f8d88612f88600460008c6001600160a01b03166001600160a01b031681526020019081526020016000208761ffff1681548110612f6857fe5b600091825260209091206002909102015462010000900461ffff16611f34565b612dac565b6001600160a01b0389166000908152600460205260409020805461ffff8716908110612fb557fe5b60009182526020918290206040805160e0810182526002909302909101805461ffff8082168552620100008204169484019490945263ffffffff600160201b8504811692840192909252600160401b840490911660608301526001600160801b03600160601b909304831660808301526001015480831660a0830152600160801b900490911660c0820152614bae565b839063ffffffff61348916565b9150600101612ef2565b509392505050565b60408051600160e01b63b3129e1f028152600e60048201526001600160a01b0383166024820152905160009173ed4d05496c71e71cc2a8726af1242c22108d17619163b3129e1f91604480820192602092909190829003018186803b158015611f9757600080fd5b6130d633846131d6565b156130e5576130e53384613254565b6130ed612ee6565b63ffffffff168163ffffffff16101561313a57604051600160e51b62461bcd028152600401808060200182810382526022815260200180615abe6022913960400191505060405180910390fd5b60408051808201825283815263ffffffff83811660208084018281523360008181528084528781206001600160a01b038c16808352908552908890209651600388015591516004909601805463ffffffff19169690951695909517909355845187815290810191909152835191937f2c6245af506f0fc1089918c02c1d01bde9cc807609b334b3e7644d6dfb5a6c5e92918290030190a3505050565b60006131e0612ee6565b6001600160a01b038085166000908152602081815260408083209387168352929052206004015463ffffffff91821691161080156129d05750506001600160a01b0391821660009081526020818152604080832093909416825291909152206004015463ffffffff16151590565b60025481565b61325e8282614a75565b613266612ee6565b6001600160a01b038084166000908152602081815260408083209386168352929052206004015463ffffffff9182169116106132d657604051600160e51b62461bcd0281526004018080602001828103825260268152602001806159be6026913960400191505060405180910390fd5b6132de612ee6565b6001600160a01b0380841660009081526001602090815260408083209386168352929052205463ffffffff91821691161061334d57604051600160e51b62461bcd0281526004018080602001828103825260458152602001806158b86045913960600191505060405180910390fd5b6001600160a01b03828116600090815260208181526040808320938516835292905290812080546003909101546133849190614b98565b6001600160a01b03808516600090815260208181526040808320938716835292905220549091506133bb908263ffffffff6147a616565b6001600160a01b0384811660009081526020818152604080832093871683529290529081209182556003820155600401805463ffffffff19169055613401828483614dc0565b816001600160a01b0316836001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb836040518082815260200191505060405180910390a3505050565b601e81565b60006001613462612ee6565b60065463ffffffff908116929091031614156134815750600b546112d2565b5060006112d2565b6060806040519050835180825260208201818101602087015b818310156134ba5780518352602092830192016134a2565b50855184518101855292509050808201602086015b818310156134e75780518352602092830192016134cf565b508651929092011591909101601f01601f191660405250905092915050565b60408051600160e01b63ab8978b7028152600e600482015261ffff88166024820152905160009173ed4d05496c71e71cc2a8726af1242c22108d17619163ab8978b791604480820192602092909190829003018186803b15801561356957600080fd5b505af415801561357d573d6000803e3d6000fd5b505050506040513d602081101561359357600080fd5b50516135e95760408051600160e51b62461bcd02815260206004820152601860248201527f42757920746f6b656e206d757374206265206c69737465640000000000000000604482015290519081900360640190fd5b60408051600160e01b63ab8978b7028152600e600482015261ffff88166024820152905173ed4d05496c71e71cc2a8726af1242c22108d17619163ab8978b7916044808301926020929190829003018186803b15801561364857600080fd5b505af415801561365c573d6000803e3d6000fd5b505050506040513d602081101561367257600080fd5b50516136c85760408051600160e51b62461bcd02815260206004820152601960248201527f53656c6c20746f6b656e206d757374206265206c697374656400000000000000604482015290519081900360640190fd5b8561ffff168761ffff1614156137285760408051600160e51b62461bcd02815260206004820152601c60248201527f45786368616e676520746f6b656e73206e6f742064697374696e637400000000604482015290519081900360640190fd5b613730612ee6565b63ffffffff168563ffffffff16101561377d57604051600160e51b62461bcd0281526004018080602001828103825260228152602001806159296022913960400191505060405180910390fd5b60046000336001600160a01b03166001600160a01b031681526020019081526020016000206040518060e001604052808961ffff1681526020018861ffff1681526020018763ffffffff1681526020018663ffffffff168152602001856001600160801b03168152602001846001600160801b0316815260200160006001600160801b03168152509080600181540180825580915050906001820390600052602060002090600202016000909192909190915060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a81548161ffff021916908361ffff16021790555060408201518160000160046101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160086101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600c6101000a8154816001600160801b0302191690836001600160801b0316021790555060a08201518160010160006101000a8154816001600160801b0302191690836001600160801b0316021790555060c08201518160010160106101000a8154816001600160801b0302191690836001600160801b031602179055505050506000613984600160046000336001600160a01b03166001600160a01b031681526020019081526020016000208054905003614e15565b6040805161ffff808416825263ffffffff808b1660208401528916828401526001600160801b038089166060840152871660808301529151929350818a1692918b169133917fdecf6fde8243981299f7b7a776f29a9fc67a2c9848e25d77c50eb11fa58a7e21919081900360a00190a460408051600160e11b634743bd03028152600c6004820152336024820152905173cddb32b6bb2808d5b5115daab207479ce98d263691638e877a06916044808301926020929190829003018186803b158015613a4f57600080fd5b505af4158015613a63573d6000803e3d6000fd5b505050506040513d6020811015613a7957600080fd5b509098975050505050505050565b6000613aa26065613a96613456565b9063ffffffff61423616565b613ab383606463ffffffff61423616565b1192915050565b6000805b8251811015613b08576127106001600160801b0316838281518110613adf57fe5b60200260200101516001600160801b03161015613b00576000915050611fc6565b600101613abe565b50600192915050565b600060015b8251811015613b0857826001820381518110613b2e57fe5b602002602001015161ffff16838281518110613b4657fe5b602002602001015161ffff1611613b61576000915050611fc6565b600101613b16565b6000613b73614e5f565b613bf857600354600a5460408051600160e01b634417f4db028152306004820152602481019290925251620100009092046001600160a01b031691634417f4db9160448082019260009290919082900301818387803b158015613bd557600080fd5b505af1158015613be9573d6000803e3d6000fd5b5050600a5492506112d2915050565b50600090565b613c06614e5f565b15613fcb5760005b600754811015613d9b57600060066001018281548110613c2a57fe5b60009182526020822060029091020154600780546001600160a01b0390921693509084908110613c5657fe5b906000526020600020906002020160010160109054906101000a900461ffff169050613c80615641565b6001600160a01b0383166000908152600460205260409020805461ffff8416908110613ca857fe5b600091825260208083206040805160e0810182526002909402909101805461ffff8082168652620100008204169385019390935263ffffffff600160201b8404811692850192909252600160401b830490911660608401526001600160801b03600160601b909204821660808401526001015480821660a0840152600160801b90041660c082015260078054919350613d689187908110613d4557fe5b60009182526020909120600160029092020101546001600160801b031683614125565b915050613d8b84613d7c8460200151611f34565b836001600160801b0316614e81565b505060019092019150613c0e9050565b5060005b600754811015613fa857600060066001018281548110613dbb57fe5b60009182526020822060029091020154600780546001600160a01b0390921693509084908110613de757fe5b906000526020600020906002020160010160109054906101000a900461ffff169050613e11615641565b6001600160a01b0383166000908152600460205260409020805461ffff8416908110613e3957fe5b600091825260208083206040805160e0810182526002909402909101805461ffff8082168652620100008204169385019390935263ffffffff600160201b8404811692850192909252600160401b830490911660608401526001600160801b03600160601b909204821660808401526001015480821660a0840152600160801b90041660c0820152600780549193508291613efc919088908110613ed957fe5b60009182526020909120600160029092020101546001600160801b031684614125565b91509150613f0b858583614eee565b613f2b85613f1c8560000151611f34565b846001600160801b0316614f8e565b60208084015184516040805161ffff92831681526001600160801b0380871695820195909552938616848201525191811692908716916001600160a01b038916917fb7214f648cea2a7c47aaea7e7aafef610de8d04366d26f66879d076516964eae919081900360600190a4505060019093019250613d9f915050565b50600954613fcb906001600160a01b0316613fc36000611f34565b600a54614f8e565b565b60005b6008548110156140465760006005600060066002018481548110613ff057fe5b60009182526020808320601083040154600f9092166002026101000a90910461ffff168352820192909252604001902080546001600160801b0319166001600160801b0392909216919091179055600101613fd0565b5060005b81518110156125d45782818151811061405f57fe5b60200260200101516005600084848151811061407757fe5b60209081029190910181015161ffff16825281019190915260400160002080546001600160801b0319166001600160801b039290921691909117905560010161404a565b606081516001016040519080825280602002602001820160405280156140eb578160200160208202803883390190505b5092915050565b60008163ffffffff16836040015163ffffffff16111580156129d057505060609091015163ffffffff9182169116101590565b805161ffff9081166000908152600560209081526040808320549185015190931682529181205490918291829161416a9187916001600160801b039081169116614fcc565b94959350505050565b600061417f8685615003565b9050600061418d8686615003565b90506141be846001600160801b03168984815181106141a857fe5b60200260200101516150ec90919063ffffffff16565b8883815181106141ca57fe5b602002602001018181525050614205836001600160801b03168983815181106141ef57fe5b602002602001015161515490919063ffffffff16565b88828151811061421157fe5b6020026020010181815250505050505050505050565b60c081015160a0909101510390565b60008261424557506000612253565b8282028284828161425257fe5b04146129d057604051600160e51b62461bcd02815260040180806020018281038252602181526020018061597c6021913960400191505060405180910390fd5b6080810151815161ffff90811660009081526005602090815260408083205491860151909316825291812054909283926142f7926001600160801b03928316926142e29289929082169116614fcc565b6001600160801b03169063ffffffff61423616565b835161ffff1660009081526005602052604081205460a08601519293509091614352916001600160801b0390811691613a969161433c9187911663ffffffff6151bc16565b6001600160801b0389169063ffffffff6147a616565b60a085018051865161ffff166000908152600560205260408120549251939450926143a9926001600160801b039283169261439d9291811691613a969189911663ffffffff6151fe16565b9063ffffffff6151bc16565b90506143bb828263ffffffff6147a616565b9695505050505050565b6000828201838110156129d05760408051600160e51b62461bcd02815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038316600090815260046020526040902080546144df919061ffff851690811061444f57fe5b60009182526020918290206040805160e0810182526002909302909101805461ffff8082168552620100008204169484019490945263ffffffff600160201b8504811692840192909252600160401b840490911660608301526001600160801b03600160601b909304831660808301526001015480831660a0830152600160801b900490911660c0820152615240565b156125d457614557614552826001600160801b031660046000876001600160a01b03166001600160a01b031681526020019081526020016000208561ffff168154811061452857fe5b6000918252602090912060029091020160010154600160801b90046001600160801b0316906143c5565b61527a565b6001600160a01b0384166000908152600460205260409020805461ffff851690811061457f57fe5b906000526020600020906002020160010160106101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b6145c383836131d6565b1561460e576145d0612ee6565b6001600160a01b038481166000908152600160209081526040808320938716835292905220805463ffffffff191663ffffffff929092169190911790555b6125d4838383614e81565b6146238383612dac565b81111561467a5760408051600160e51b62461bcd02815260206004820152601e60248201527f416d6f756e742065786365656473207573657227732062616c616e63652e0000604482015290519081900360640190fd5b6125d4838383614f8e565b6000806146b361469485614227565b6001600160801b03166146ae85612f888860200151611f34565b614b98565b60a085015160208087015161ffff16600090815260059091526040812054929350916146f1916001600160801b03918216911663ffffffff61423616565b855161ffff166000908152600560205260408120546080880151929350909161473c916103e79161439d916103e891613a96916001600160801b03918216911663ffffffff61423616565b905060008183111561475b57614758838363ffffffff6147a616565b90505b60a087015161477d906001600160801b031661439d868463ffffffff61423616565b979650505050505050565b60008160008151811061479757fe5b60200260200101519050919050565b60006129d083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506152c1565b6147f181613a87565b61482f57604051600160e51b62461bcd02815260040180806020018281038252603b815260200180615806603b913960400191505060405180910390fd5b600b55565b600a81905561484d336148476000611f34565b836145b9565b50565b60008160008151811061485f57fe5b6020026020010151136148a657604051600160e51b62461bcd028152600401808060200182810382526029815260200180615a236029913960400191505060405180910390fd5b60015b8151811015611fdd578181815181106148be57fe5b602002602001015160001461491d5760408051600160e51b62461bcd02815260206004820181905260248201527f546f6b656e20636f6e736572766174696f6e20646f6573206e6f7420686f6c64604482015290519081900360640190fd5b6001016148a9565b6006805463ffffffff191663ffffffff871617905560005b8451811015614a47576006600101604051806060016040528087848151811061496257fe5b60200260200101516001600160a01b0316815260200185848151811061498457fe5b60200260200101516001600160801b031681526020018684815181106149a657fe5b60209081029190910181015161ffff908116909252835460018082018655600095865294829020845160029092020180546001600160a01b0319166001600160a01b039092169190911781559083015190840180546040909401516001600160801b03199094166001600160801b039092169190911771ffff000000000000000000000000000000001916600160801b93909216929092021790550161493d565b508051614a5b906008906020840190615694565b5050600980546001600160a01b0319163317905550505050565b6001600160a01b038083166000908152602081815260408083209385168352929052206002015463ffffffff168015801590614abd5750614ab4612ee6565b63ffffffff1681105b156125d4576001600160a01b0383811660009081526020818152604080832093861683529290522060018101549054614af5916143c5565b6001600160a01b0393841660009081526020818152604080832095909616825293909352928220928355506001820155600201805463ffffffff19169055565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b0316600160e01b6323b872dd02179052614b9290859061535b565b50505050565b6000818310614ba757816129d0565b5090919050565b604080516001600160a01b03851660601b6020820152815180820360140181526034820183526054808301869052835180840390910181526074909201909252614bff90829063ffffffff61348916565b82516040805161ffff90921660f01b60208301528051808303600201815260229092019052909150614c3890829063ffffffff61348916565b9050614c7b8260200151604051602001808261ffff1661ffff1660f01b81526002019150506040516020818303038152906040528261348990919063ffffffff16565b604080840151815163ffffffff91821660e01b6020820152825180820360040181526024909101909252919250614cb59183919061348916565b60608301516040805163ffffffff92831660e01b6020820152815180820360040181526024909101909152919250614cef91839161348916565b9050614d3c826080015160405160200180826001600160801b03166001600160801b031660801b81526010019150506040516020818303038152906040528261348990919063ffffffff16565b60a0830151604080516001600160801b0390921660801b60208301528051808303601001815260309092019052909150614d7d90829063ffffffff61348916565b9050612ecd614d8b83614227565b604080516001600160801b0390921660801b60208301528051808303601001815260309092019052829063ffffffff61348916565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0316600160e01b63a9059cbb021790526125d490849061535b565b6000620100008210614e5b57604051600160e51b62461bcd02815260040180806020018281038252602681526020018061579a6026913960400191505060405180910390fd5b5090565b60006001614e6b612ee6565b60065463ffffffff908116929091031614905090565b614e8b8383614a75565b6001600160a01b0380841660009081526020818152604080832093861683529290522054614ebf908263ffffffff6143c516565b6001600160a01b0393841660009081526020818152604080832095909616825293909352929091209190915550565b6001600160a01b03831660009081526004602052604090208054614f1b919061ffff851690811061444f57fe5b156125d457614557614552826001600160801b031660046000876001600160a01b03166001600160a01b031681526020019081526020016000208561ffff1681548110614f6457fe5b6000918252602090912060029091020160010154600160801b90046001600160801b0316906147a6565b614f988383614a75565b6001600160a01b0380841660009081526020818152604080832093861683529290522054614ebf908263ffffffff6147a616565b6000612ecd6145526001600160801b038085169061439d906103e890613a96906103e79084908c8116908c1663ffffffff61423616565b600061ffff831661501657506000612253565b8151600090600019015b81811061509c57600060028383010490508561ffff1685828151811061504257fe5b602002602001015161ffff161415615061576001019250612253915050565b8561ffff1685828151811061507257fe5b602002602001015161ffff16101561508f57806001019250615096565b6001810391505b50615020565b60408051600160e51b62461bcd02815260206004820152601c60248201527f5072696365206e6f742070726f766964656420666f7220746f6b656e00000000604482015290519081900360640190fd5b60008183038183128015906151015750838113155b80615116575060008312801561511657508381135b6129d057604051600160e51b62461bcd028152600401808060200182810382526024815260200180615a706024913960400191505060405180910390fd5b60008282018183128015906151695750838112155b8061517e575060008312801561517e57508381125b6129d057604051600160e51b62461bcd0281526004018080602001828103825260218152602001806158686021913960400191505060405180910390fd5b60006129d083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061551c565b60006129d083836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250615584565b60006000196001600160801b031682608001516001600160801b03161415801561225357505060a001516001600160801b03908116141590565b6000600160801b8210614e5b57604051600160e51b62461bcd0281526004018080602001828103825260278152602001806158416027913960400191505060405180910390fd5b6000818484111561535357604051600160e51b62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615318578181015183820152602001615300565b50505050905090810190601f1680156153455780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b61536d826001600160a01b03166155e9565b6153c15760408051600160e51b62461bcd02815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106153ff5780518252601f1990920191602091820191016153e0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114615461576040519150601f19603f3d011682016040523d82523d6000602084013e615466565b606091505b5091509150816154c05760408051600160e51b62461bcd02815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115614b92578080602001905160208110156154dc57600080fd5b5051614b9257604051600160e51b62461bcd02815260040180806020018281038252602a815260200180615a94602a913960400191505060405180910390fd5b6000818361556e57604051600160e51b62461bcd028152602060048201818152835160248401528351909283926044909101919085019080838360008315615318578181015183820152602001615300565b50600083858161557a57fe5b0495945050505050565b600081836155d657604051600160e51b62461bcd028152602060048201818152835160248401528351909283926044909101919085019080838360008315615318578181015183820152602001615300565b508284816155e057fe5b06949350505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708115801590612ecd5750141592915050565b508054600082556002029060005260206000209081019061484d9190615739565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b82805482825590600052602060002090600f0160109004810192821561572d5791602002820160005b838211156156fd57835183826101000a81548161ffff021916908361ffff16021790555092602001926002016020816001010492830192600103026156bd565b801561572b5782816101000a81549061ffff02191690556002016020816001010492830192600103026156fd565b505b50614e5b92915061577a565b6112d291905b80821115614e5b5780546001600160a01b031916815560018101805471ffffffffffffffffffffffffffffffffffff1916905560020161573f565b6112d291905b80821115614e5b57805461ffff1916815560010161578056fe53616665436173743a2076616c756520646f65736e27742066697420696e203136206269747362757920616d6f756e74206c657373207468616e20414d4f554e545f4d494e494d554d536f6c7574696f6e2065786365656473204d41585f544f55434845445f4f52444552534e6577206f626a65637469766520646f65736e27742073756666696369656e746c7920696d70726f76652063757272656e7420736f6c7574696f6e53616665436173743a2076616c756520646f65736e27742066697420696e2031323820626974735369676e6564536166654d6174683a206164646974696f6e206f766572666c6f77536f6c7574696f6e7320617265206e6f206c6f6e67657220616363657074656420666f7220746869732062617463685769746864726177206e6f7420706f737369626c6520666f7220746f6b656e20746861742069732074726164656420696e207468652063757272656e742061756374696f6e4174206c65617374206f6e65207072696365206c6f776572207468616e20414d4f554e545f4d494e494d554d4f72646572732063616e277420626520706c6163656420696e207468652070617374657865637574656453656c6c416d6f756e7420626967676572207468616e2073706563696669656420696e206f72646572536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7770726963657320617265206e6f74206f72646572656420627920746f6b656e4964776974686472617720776173206e6f7420726567697374657265642070726576696f75736c79436c61696d6564206f626a65637469766520646f65736e27742073756666696369656e746c7920696d70726f76652063757272656e7420736f6c7574696f6e546f6b656e20636f6e736572766174696f6e2061742030206d75737420626520706f7369746976652e73656c6c20616d6f756e74206c657373207468616e20414d4f554e545f4d494e494d554d5369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564526571756573742063616e6e6f74206265206d61646520696e207468652070617374a165627a7a7230582073ef6c40df46039e6be6d195731df39de7c70e851409dcab570af49ff8ec1aca0029
Verified Source Code Partial Match
Compiler: v0.5.6+commit.b259423e
EVM: petersburg
Optimization: Yes (200 runs)
BatchExchange.sol 2700 lines
pragma solidity ^0.5.0;
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* NOTE: This is a feature of the next version of OpenZeppelin Contracts.
* @dev Get it via `npm install @openzeppelin/contracts@next`.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
* NOTE: This is a feature of the next version of OpenZeppelin Contracts.
* @dev Get it via `npm install @openzeppelin/contracts@next`.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* NOTE: This is a feature of the next version of OpenZeppelin Contracts.
* @dev Get it via `npm install @openzeppelin/contracts@next`.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* This test is non-exhaustive, and there may be false-negatives: during the
* execution of a contract's constructor, its address will be reported as
* not containing a contract.
*
* IMPORTANT: It is unsafe to assume that an address for which this
* function returns false is an externally-owned account (EOA) and not a
* contract.
*/
function isContract(address account) internal view returns (bool) {
// This method relies in extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != 0x0 && codehash != accountHash);
}
/**
* @dev Converts an `address` into `address payable`. Note that this is
* simply a type cast: the actual underlying value is not changed.
*
* NOTE: This is a feature of the next version of OpenZeppelin Contracts.
* @dev Get it via `npm install @openzeppelin/contracts@next`.
*/
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
}
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves.
// A Solidity high level call has three parts:
// 1. The target address is checked to verify it contains contract code
// 2. The call itself is made, and success asserted
// 3. The return value is decoded, which in turn checks the size of the returned data.
// solhint-disable-next-line max-line-length
require(address(token).isContract(), "SafeERC20: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
contract EpochTokenLocker {
using SafeMath for uint256;
/** @dev Number of seconds a batch is lasting*/
uint32 public constant BATCH_TIME = 300;
// User => Token => BalanceState
mapping(address => mapping(address => BalanceState)) private balanceStates;
// user => token => lastCreditBatchId
mapping(address => mapping(address => uint32)) public lastCreditBatchId;
struct BalanceState {
uint256 balance;
PendingFlux pendingDeposits; // deposits will be credited in any future epoch, i.e. currentStateIndex > batchId
PendingFlux pendingWithdraws; // withdraws are allowed in any future epoch, i.e. currentStateIndex > batchId
}
struct PendingFlux {
uint256 amount;
uint32 batchId;
}
event Deposit(address indexed user, address indexed token, uint256 amount, uint32 batchId);
event WithdrawRequest(address indexed user, address indexed token, uint256 amount, uint32 batchId);
event Withdraw(address indexed user, address indexed token, uint256 amount);
/** @dev credits user with deposit amount on next epoch (given by getCurrentBatchId)
* @param token address of token to be deposited
* @param amount number of token(s) to be credited to user's account
*
* Emits an {Deposit} event with relevent deposit information.
*
* Requirements:
* - token transfer to contract is successfull
*/
function deposit(address token, uint256 amount) public {
updateDepositsBalance(msg.sender, token);
SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount);
// solhint-disable-next-line max-line-length
balanceStates[msg.sender][token].pendingDeposits.amount = balanceStates[msg.sender][token].pendingDeposits.amount.add(
amount
);
balanceStates[msg.sender][token].pendingDeposits.batchId = getCurrentBatchId();
emit Deposit(msg.sender, token, amount, getCurrentBatchId());
}
/** @dev Signals and initiates user's intent to withdraw.
* @param token address of token to be withdrawn
* @param amount number of token(s) to be withdrawn
*
* Emits an {WithdrawRequest} event with relevent request information.
*/
function requestWithdraw(address token, uint256 amount) public {
requestFutureWithdraw(token, amount, getCurrentBatchId());
}
/** @dev Signals and initiates user's intent to withdraw.
* @param token address of token to be withdrawn
* @param amount number of token(s) to be withdrawn
* @param batchId state index at which request is to be made.
*
* Emits an {WithdrawRequest} event with relevent request information.
*/
function requestFutureWithdraw(address token, uint256 amount, uint32 batchId) public {
// First process pendingWithdraw (if any), as otherwise balances might increase for currentBatchId - 1
if (hasValidWithdrawRequest(msg.sender, token)) {
withdraw(msg.sender, token);
}
require(batchId >= getCurrentBatchId(), "Request cannot be made in the past");
balanceStates[msg.sender][token].pendingWithdraws = PendingFlux({amount: amount, batchId: batchId});
emit WithdrawRequest(msg.sender, token, amount, batchId);
}
/** @dev Claims pending withdraw - can be called on behalf of others
* @param token address of token to be withdrawn
* @param user address of user who withdraw is being claimed.
*
* Emits an {Withdraw} event stating that `user` withdrew `amount` of `token`
*
* Requirements:
* - withdraw was requested in previous epoch
* - token was received from exchange in current auction batch
*/
function withdraw(address user, address token) public {
updateDepositsBalance(user, token); // withdrawn amount may have been deposited in previous epoch
require(
balanceStates[user][token].pendingWithdraws.batchId < getCurrentBatchId(),
"withdraw was not registered previously"
);
require(
lastCreditBatchId[user][token] < getCurrentBatchId(),
"Withdraw not possible for token that is traded in the current auction"
);
uint256 amount = Math.min(balanceStates[user][token].balance, balanceStates[user][token].pendingWithdraws.amount);
balanceStates[user][token].balance = balanceStates[user][token].balance.sub(amount);
delete balanceStates[user][token].pendingWithdraws;
SafeERC20.safeTransfer(IERC20(token), user, amount);
emit Withdraw(user, token, amount);
}
/**
* Public view functions
*/
/** @dev getter function used to display pending deposit
* @param user address of user
* @param token address of ERC20 token
* return amount and batchId of deposit's transfer if any (else 0)
*/
function getPendingDeposit(address user, address token) public view returns (uint256, uint32) {
PendingFlux memory pendingDeposit = balanceStates[user][token].pendingDeposits;
return (pendingDeposit.amount, pendingDeposit.batchId);
}
/** @dev getter function used to display pending withdraw
* @param user address of user
* @param token address of ERC20 token
* return amount and batchId when withdraw was requested if any (else 0)
*/
function getPendingWithdraw(address user, address token) public view returns (uint256, uint32) {
PendingFlux memory pendingWithdraw = balanceStates[user][token].pendingWithdraws;
return (pendingWithdraw.amount, pendingWithdraw.batchId);
}
/** @dev getter function to determine current auction id.
* return current batchId
*/
function getCurrentBatchId() public view returns (uint32) {
// solhint-disable-next-line not-rely-on-time
return uint32(now / BATCH_TIME);
}
/** @dev used to determine how much time is left in a batch
* return seconds remaining in current batch
*/
function getSecondsRemainingInBatch() public view returns (uint256) {
// solhint-disable-next-line not-rely-on-time
return BATCH_TIME - (now % BATCH_TIME);
}
/** @dev fetches and returns user's balance
* @param user address of user
* @param token address of ERC20 token
* return Current `token` balance of `user`'s account
*/
function getBalance(address user, address token) public view returns (uint256) {
uint256 balance = balanceStates[user][token].balance;
if (balanceStates[user][token].pendingDeposits.batchId < getCurrentBatchId()) {
balance = balance.add(balanceStates[user][token].pendingDeposits.amount);
}
if (balanceStates[user][token].pendingWithdraws.batchId < getCurrentBatchId()) {
balance = balance.sub(Math.min(balanceStates[user][token].pendingWithdraws.amount, balance));
}
return balance;
}
/** @dev Used to determine if user has a valid pending withdraw request of specific token
* @param user address of user
* @param token address of ERC20 token
* return true if `user` has valid withdraw request for `token`, otherwise false
*/
function hasValidWithdrawRequest(address user, address token) public view returns (bool) {
return
balanceStates[user][token].pendingWithdraws.batchId < getCurrentBatchId() &&
balanceStates[user][token].pendingWithdraws.batchId > 0;
}
/**
* internal functions
*/
/**
* The following function should be used to update any balances within an epoch, which
* will not be immediately final. E.g. the BatchExchange credits new balances to
* the buyers in an auction, but as there are might be better solutions, the updates are
* not final. In order to prevent withdraws from non-final updates, we disallow withdraws
* by setting lastCreditBatchId to the current batchId and allow only withdraws in batches
* with a higher batchId.
*/
function addBalanceAndBlockWithdrawForThisBatch(address user, address token, uint256 amount) internal {
if (hasValidWithdrawRequest(user, token)) {
lastCreditBatchId[user][token] = getCurrentBatchId();
}
addBalance(user, token, amount);
}
function addBalance(address user, address token, uint256 amount) internal {
updateDepositsBalance(user, token);
balanceStates[user][token].balance = balanceStates[user][token].balance.add(amount);
}
/**
* The following function should be used to subtract amounts from the current balances state.
* For the substraction the current withdrawRequests are considered and they are effectively reducing
* the available balance.
*/
function subtractBalance(address user, address token, uint256 amount) internal {
require(amount <= getBalance(user, token), "Amount exceeds user's balance.");
subtractBalanceUnchecked(user, token, amount);
}
/**
* The following function should be used to substract amounts from the current balance
* state, if the pending withdrawRequests are not considered and should not effectively reduce
* the available balance.
* For example, the reversion of trades from a previous batch-solution do not
* need to consider withdrawRequests. This is the case as withdraws are blocked for one
* batch for accounts having credited funds in a previous submission.
* PendingWithdraws must also be ignored since otherwise for the reversion of trades,
* a solution reversion could be blocked: A bigger withdrawRequest could set the return value of
* getBalance(user, token) to zero, although the user was just credited tokens in
* the last submission. In this situation, during the unwinding of the previous orders,
* the check `amount <= getBalance(user, token)` would fail and the reversion would be blocked.
*/
function subtractBalanceUnchecked(address user, address token, uint256 amount) internal {
updateDepositsBalance(user, token);
balanceStates[user][token].balance = balanceStates[user][token].balance.sub(amount);
}
function updateDepositsBalance(address user, address token) private {
uint256 batchId = balanceStates[user][token].pendingDeposits.batchId;
if (batchId > 0 && batchId < getCurrentBatchId()) {
// batchId > 0 is checked in order save an SSTORE in case there is no pending deposit
balanceStates[user][token].balance = balanceStates[user][token].balance.add(
balanceStates[user][token].pendingDeposits.amount
);
delete balanceStates[user][token].pendingDeposits;
}
}
}
library IdToAddressBiMap {
struct Data {
mapping(uint16 => address) idToAddress;
mapping(address => uint16) addressToId;
}
function hasId(Data storage self, uint16 id) public view returns (bool) {
return self.idToAddress[id + 1] != address(0);
}
function hasAddress(Data storage self, address addr) public view returns (bool) {
return self.addressToId[addr] != 0;
}
function getAddressAt(Data storage self, uint16 id) public view returns (address) {
require(hasId(self, id), "Must have ID to get Address");
return self.idToAddress[id + 1];
}
function getId(Data storage self, address addr) public view returns (uint16) {
require(hasAddress(self, addr), "Must have Address to get ID");
return self.addressToId[addr] - 1;
}
function insert(Data storage self, uint16 id, address addr) public returns (bool) {
require(addr != address(0), "Cannot insert zero address");
require(id != uint16(-1), "Cannot insert max uint16");
// Ensure bijectivity of the mappings
if (self.addressToId[addr] != 0 || self.idToAddress[id + 1] != address(0)) {
return false;
}
self.idToAddress[id + 1] = addr;
self.addressToId[addr] = id + 1;
return true;
}
}
library IterableAppendOnlySet {
struct Data {
mapping(address => address) nextMap;
address last;
}
function insert(Data storage self, address value) public returns (bool) {
if (contains(self, value)) {
return false;
}
self.nextMap[self.last] = value;
self.last = value;
return true;
}
function contains(Data storage self, address value) public view returns (bool) {
require(value != address(0), "Inserting address(0) is not supported");
return self.nextMap[value] != address(0) || (self.last == value);
}
function first(Data storage self) public view returns (address) {
require(self.last != address(0), "Trying to get first from empty set");
return self.nextMap[address(0)];
}
function next(Data storage self, address value) public view returns (address) {
require(contains(self, value), "Trying to get next of non-existent element");
require(value != self.last, "Trying to get next of last element");
return self.nextMap[value];
}
function size(Data storage self) public view returns (uint256) {
if (self.last == address(0)) {
return 0;
}
uint256 count = 1;
address current = first(self);
while (current != self.last) {
current = next(self, current);
count++;
}
return count;
}
function atIndex(Data storage self, uint256 index) public view returns (address) {
require(index < size(self), "requested index too large");
address res = first(self);
for (uint256 i = 0; i < index; i++) {
res = next(self, res);
}
return res;
}
}
library GnosisMath {
/*
* Constants
*/
// This is equal to 1 in our calculations
uint public constant ONE = 0x10000000000000000;
uint public constant LN2 = 0xb17217f7d1cf79ac;
uint public constant LOG2_E = 0x171547652b82fe177;
/*
* Public functions
*/
/// @dev Returns natural exponential function value of given x
/// @param x x
/// @return e**x
function exp(int x) public pure returns (uint) {
// revert if x is > MAX_POWER, where
// MAX_POWER = int(mp.floor(mp.log(mpf(2**256 - 1) / ONE) * ONE))
require(x <= 2454971259878909886679);
// return 0 if exp(x) is tiny, using
// MIN_POWER = int(mp.floor(mp.log(mpf(1) / ONE) * ONE))
if (x < -818323753292969962227) return 0;
// Transform so that e^x -> 2^x
x = x * int(ONE) / int(LN2);
// 2^x = 2^whole(x) * 2^frac(x)
// ^^^^^^^^^^ is a bit shift
// so Taylor expand on z = frac(x)
int shift;
uint z;
if (x >= 0) {
shift = x / int(ONE);
z = uint(x % int(ONE));
} else {
shift = x / int(ONE) - 1;
z = ONE - uint(-x % int(ONE));
}
// 2^x = 1 + (ln 2) x + (ln 2)^2/2! x^2 + ...
//
// Can generate the z coefficients using mpmath and the following lines
// >>> from mpmath import mp
// >>> mp.dps = 100
// >>> ONE = 0x10000000000000000
// >>> print('\n'.join(hex(int(mp.log(2)**i / mp.factorial(i) * ONE)) for i in range(1, 7)))
// 0xb17217f7d1cf79ab
// 0x3d7f7bff058b1d50
// 0xe35846b82505fc5
// 0x276556df749cee5
// 0x5761ff9e299cc4
// 0xa184897c363c3
uint zpow = z;
uint result = ONE;
result += 0xb17217f7d1cf79ab * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x3d7f7bff058b1d50 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0xe35846b82505fc5 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x276556df749cee5 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x5761ff9e299cc4 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0xa184897c363c3 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0xffe5fe2c4586 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x162c0223a5c8 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x1b5253d395e * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x1e4cf5158b * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x1e8cac735 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x1c3bd650 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x1816193 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x131496 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0xe1b7 * zpow / ONE;
zpow = zpow * z / ONE;
result += 0x9c7 * zpow / ONE;
if (shift >= 0) {
if (result >> (256 - shift) > 0) return (2 ** 256 - 1);
return result << shift;
} else return result >> (-shift);
}
/// @dev Returns natural logarithm value of given x
/// @param x x
/// @return ln(x)
function ln(uint x) public pure returns (int) {
require(x > 0);
// binary search for floor(log2(x))
int ilog2 = floorLog2(x);
int z;
if (ilog2 < 0) z = int(x << uint(-ilog2));
else z = int(x >> uint(ilog2));
// z = x * 2^-⌊log₂x⌋
// so 1 <= z < 2
// and ln z = ln x - ⌊log₂x⌋/log₂e
// so just compute ln z using artanh series
// and calculate ln x from that
int term = (z - int(ONE)) * int(ONE) / (z + int(ONE));
int halflnz = term;
int termpow = term * term / int(ONE) * term / int(ONE);
halflnz += termpow / 3;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 5;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 7;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 9;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 11;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 13;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 15;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 17;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 19;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 21;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 23;
termpow = termpow * term / int(ONE) * term / int(ONE);
halflnz += termpow / 25;
return (ilog2 * int(ONE)) * int(ONE) / int(LOG2_E) + 2 * halflnz;
}
/// @dev Returns base 2 logarithm value of given x
/// @param x x
/// @return logarithmic value
function floorLog2(uint x) public pure returns (int lo) {
lo = -64;
int hi = 193;
// I use a shift here instead of / 2 because it floors instead of rounding towards 0
int mid = (hi + lo) >> 1;
while ((lo + 1) < hi) {
if (mid < 0 && x << uint(-mid) < ONE || mid >= 0 && x >> uint(mid) < ONE) hi = mid;
else lo = mid;
mid = (hi + lo) >> 1;
}
}
/// @dev Returns maximum of an array
/// @param nums Numbers to look through
/// @return Maximum number
function max(int[] memory nums) public pure returns (int maxNum) {
require(nums.length > 0);
maxNum = -2 ** 255;
for (uint i = 0; i < nums.length; i++) if (nums[i] > maxNum) maxNum = nums[i];
}
/// @dev Returns whether an add operation causes an overflow
/// @param a First addend
/// @param b Second addend
/// @return Did no overflow occur?
function safeToAdd(uint a, uint b) internal pure returns (bool) {
return a + b >= a;
}
/// @dev Returns whether a subtraction operation causes an underflow
/// @param a Minuend
/// @param b Subtrahend
/// @return Did no underflow occur?
function safeToSub(uint a, uint b) internal pure returns (bool) {
return a >= b;
}
/// @dev Returns whether a multiply operation causes an overflow
/// @param a First factor
/// @param b Second factor
/// @return Did no overflow occur?
function safeToMul(uint a, uint b) internal pure returns (bool) {
return b == 0 || a * b / b == a;
}
/// @dev Returns sum if no overflow occurred
/// @param a First addend
/// @param b Second addend
/// @return Sum
function add(uint a, uint b) internal pure returns (uint) {
require(safeToAdd(a, b));
return a + b;
}
/// @dev Returns difference if no overflow occurred
/// @param a Minuend
/// @param b Subtrahend
/// @return Difference
function sub(uint a, uint b) internal pure returns (uint) {
require(safeToSub(a, b));
return a - b;
}
/// @dev Returns product if no overflow occurred
/// @param a First factor
/// @param b Second factor
/// @return Product
function mul(uint a, uint b) internal pure returns (uint) {
require(safeToMul(a, b));
return a * b;
}
/// @dev Returns whether an add operation causes an overflow
/// @param a First addend
/// @param b Second addend
/// @return Did no overflow occur?
function safeToAdd(int a, int b) internal pure returns (bool) {
return (b >= 0 && a + b >= a) || (b < 0 && a + b < a);
}
/// @dev Returns whether a subtraction operation causes an underflow
/// @param a Minuend
/// @param b Subtrahend
/// @return Did no underflow occur?
function safeToSub(int a, int b) internal pure returns (bool) {
return (b >= 0 && a - b <= a) || (b < 0 && a - b > a);
}
/// @dev Returns whether a multiply operation causes an overflow
/// @param a First factor
/// @param b Second factor
/// @return Did no overflow occur?
function safeToMul(int a, int b) internal pure returns (bool) {
return (b == 0) || (a * b / b == a);
}
/// @dev Returns sum if no overflow occurred
/// @param a First addend
/// @param b Second addend
/// @return Sum
function add(int a, int b) internal pure returns (int) {
require(safeToAdd(a, b));
return a + b;
}
/// @dev Returns difference if no overflow occurred
/// @param a Minuend
/// @param b Subtrahend
/// @return Difference
function sub(int a, int b) internal pure returns (int) {
require(safeToSub(a, b));
return a - b;
}
/// @dev Returns product if no overflow occurred
/// @param a First factor
/// @param b Second factor
/// @return Product
function mul(int a, int b) internal pure returns (int) {
require(safeToMul(a, b));
return a * b;
}
}
contract Token {
/*
* Events
*/
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
/*
* Public functions
*/
function transfer(address to, uint value) public returns (bool);
function transferFrom(address from, address to, uint value) public returns (bool);
function approve(address spender, uint value) public returns (bool);
function balanceOf(address owner) public view returns (uint);
function allowance(address owner, address spender) public view returns (uint);
function totalSupply() public view returns (uint);
}
contract Proxied {
address public masterCopy;
}
contract Proxy is Proxied {
/// @dev Constructor function sets address of master copy contract.
/// @param _masterCopy Master copy address.
constructor(address _masterCopy) public {
require(_masterCopy != address(0), "The master copy is required");
masterCopy = _masterCopy;
}
/// @dev Fallback function forwards all transactions and returns all received return data.
function() external payable {
address _masterCopy = masterCopy;
assembly {
calldatacopy(0, 0, calldatasize)
let success := delegatecall(not(0), _masterCopy, 0, calldatasize, 0, 0)
returndatacopy(0, 0, returndatasize)
switch success
case 0 {
revert(0, returndatasize)
}
default {
return(0, returndatasize)
}
}
}
}
contract StandardTokenData {
/*
* Storage
*/
mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowances;
uint totalTokens;
}
contract GnosisStandardToken is Token, StandardTokenData {
using GnosisMath for *;
/*
* Public functions
*/
/// @dev Transfers sender's tokens to a given address. Returns success
/// @param to Address of token receiver
/// @param value Number of tokens to transfer
/// @return Was transfer successful?
function transfer(address to, uint value) public returns (bool) {
if (!balances[msg.sender].safeToSub(value) || !balances[to].safeToAdd(value)) {
return false;
}
balances[msg.sender] -= value;
balances[to] += value;
emit Transfer(msg.sender, to, value);
return true;
}
/// @dev Allows allowed third party to transfer tokens from one address to another. Returns success
/// @param from Address from where tokens are withdrawn
/// @param to Address to where tokens are sent
/// @param value Number of tokens to transfer
/// @return Was transfer successful?
function transferFrom(address from, address to, uint value) public returns (bool) {
if (!balances[from].safeToSub(value) || !allowances[from][msg.sender].safeToSub(
value
) || !balances[to].safeToAdd(value)) {
return false;
}
balances[from] -= value;
allowances[from][msg.sender] -= value;
balances[to] += value;
emit Transfer(from, to, value);
return true;
}
/// @dev Sets approved amount of tokens for spender. Returns success
/// @param spender Address of allowed account
/// @param value Number of approved tokens
/// @return Was approval successful?
function approve(address spender, uint value) public returns (bool) {
allowances[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
/// @dev Returns number of allowed tokens for given address
/// @param owner Address of token owner
/// @param spender Address of token spender
/// @return Remaining allowance for spender
function allowance(address owner, address spender) public view returns (uint) {
return allowances[owner][spender];
}
/// @dev Returns number of tokens owned by given address
/// @param owner Address of token owner
/// @return Balance of owner
function balanceOf(address owner) public view returns (uint) {
return balances[owner];
}
/// @dev Returns total supply of tokens
/// @return Total supply
function totalSupply() public view returns (uint) {
return totalTokens;
}
}
contract TokenOWL is Proxied, GnosisStandardToken {
using GnosisMath for *;
string public constant name = "OWL Token";
string public constant symbol = "OWL";
uint8 public constant decimals = 18;
struct masterCopyCountdownType {
address masterCopy;
uint timeWhenAvailable;
}
masterCopyCountdownType masterCopyCountdown;
address public creator;
address public minter;
event Minted(address indexed to, uint256 amount);
event Burnt(address indexed from, address indexed user, uint256 amount);
modifier onlyCreator() {
// R1
require(msg.sender == creator, "Only the creator can perform the transaction");
_;
}
/// @dev trickers the update process via the proxyMaster for a new address _masterCopy
/// updating is only possible after 30 days
function startMasterCopyCountdown(address _masterCopy) public onlyCreator {
require(address(_masterCopy) != address(0), "The master copy must be a valid address");
// Update masterCopyCountdown
masterCopyCountdown.masterCopy = _masterCopy;
masterCopyCountdown.timeWhenAvailable = now + 30 days;
}
/// @dev executes the update process via the proxyMaster for a new address _masterCopy
function updateMasterCopy() public onlyCreator {
require(address(masterCopyCountdown.masterCopy) != address(0), "The master copy must be a valid address");
require(
block.timestamp >= masterCopyCountdown.timeWhenAvailable,
"It's not possible to update the master copy during the waiting period"
);
// Update masterCopy
masterCopy = masterCopyCountdown.masterCopy;
}
function getMasterCopy() public view returns (address) {
return masterCopy;
}
/// @dev Set minter. Only the creator of this contract can call this.
/// @param newMinter The new address authorized to mint this token
function setMinter(address newMinter) public onlyCreator {
minter = newMinter;
}
/// @dev change owner/creator of the contract. Only the creator/owner of this contract can call this.
/// @param newOwner The new address, which should become the owner
function setNewOwner(address newOwner) public onlyCreator {
creator = newOwner;
}
/// @dev Mints OWL.
/// @param to Address to which the minted token will be given
/// @param amount Amount of OWL to be minted
function mintOWL(address to, uint amount) public {
require(minter != address(0), "The minter must be initialized");
require(msg.sender == minter, "Only the minter can mint OWL");
balances[to] = balances[to].add(amount);
totalTokens = totalTokens.add(amount);
emit Minted(to, amount);
emit Transfer(address(0), to, amount);
}
/// @dev Burns OWL.
/// @param user Address of OWL owner
/// @param amount Amount of OWL to be burnt
function burnOWL(address user, uint amount) public {
allowances[user][msg.sender] = allowances[user][msg.sender].sub(amount);
balances[user] = balances[user].sub(amount);
totalTokens = totalTokens.sub(amount);
emit Burnt(msg.sender, user, amount);
emit Transfer(user, address(0), amount);
}
function getMasterCopyCountdown() public view returns (address, uint) {
return (masterCopyCountdown.masterCopy, masterCopyCountdown.timeWhenAvailable);
}
}
library SafeCast {
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits");
return uint8(value);
}
}
library BytesLib {
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...
// [truncated — 109600 bytes total]
Read Contract
AMOUNT_MINIMUM 0x61ed16d0 → uint128
BATCH_TIME 0xe48c015e → uint32
ENCODED_AUCTION_ELEMENT_WIDTH 0xe1d5f64e → uint128
FEE_DENOMINATOR 0xd73792a9 → uint128
FEE_FOR_LISTING_TOKEN_IN_OWL 0x41e383ed → uint256
IMPROVEMENT_DENOMINATOR 0x094c7e19 → uint256
MAX_TOKENS 0xf47c84c5 → uint256
MAX_TOUCHED_ORDERS 0xfb736d32 → uint256
UNLIMITED_ORDER_AMOUNT 0x7fb47b06 → uint128
acceptingSolutions 0xc49598fb → bool
currentPrices 0x66367c10 → uint128
feeToken 0x647846a5 → address
getBalance 0xd4fac45d → uint256
getCurrentBatchId 0xe720ac8e → uint32
getCurrentObjectiveValue 0xff97c626 → uint256
getEncodedOrders 0x23d4a3c9 → bytes
getEncodedUserOrders 0x72f3dd39 → bytes
getEncodedUserOrdersPaginated 0xed2da357 → bytes
getEncodedUsersPaginated 0x95466a46 → bytes
getPendingDeposit 0xb3c0afa1 → uint256, uint32
getPendingWithdraw 0xc33eb9f6 → uint256, uint32
getSecondsRemainingInBatch 0x17569c1d → uint256
getUsersPaginated 0x43383ac3 → bytes
hasToken 0x9bb0f599 → bool
hasValidWithdrawRequest 0xf3f47982 → bool
lastCreditBatchId 0x907767c0 → uint32
latestSolution 0x9cc84ed3 → uint32, address, uint256, uint256
numTokens 0x8e499bcf → uint16
orders 0x793b8c6d → uint16, uint16, uint32, uint32, uint128, uint128, uint128
tokenAddressToIdMap 0xef574d23 → uint16
tokenIdToAddressMap 0x2f10d082 → address
Write Contract 10 functions
These functions modify contract state and require a wallet transaction to execute.
addToken 0xd48bfca7
address token
cancelOrders 0x4bdc1b4c
uint16[] orderIds
deposit 0x47e7ef24
address token
uint256 amount
placeOrder 0x26c3d394
uint16 buyToken
uint16 sellToken
uint32 validUntil
uint128 buyAmount
uint128 sellAmount
returns: uint256
placeValidFromOrders 0x65cc3e78
uint16[] buyTokens
uint16[] sellTokens
uint32[] validFroms
uint32[] validUntils
uint128[] buyAmounts
uint128[] sellAmounts
returns: uint16[]
replaceOrders 0xc1ef2838
uint16[] cancellations
uint16[] buyTokens
uint16[] sellTokens
uint32[] validFroms
uint32[] validUntils
uint128[] buyAmounts
uint128[] sellAmounts
returns: uint16[]
requestFutureWithdraw 0xf36b6355
address token
uint256 amount
uint32 batchId
requestWithdraw 0x397a1b28
address token
uint256 amount
submitSolution 0x2e4c83bd
uint32 batchId
uint256 claimedObjectiveValue
address[] owners
uint16[] orderIds
uint128[] buyVolumes
uint128[] prices
uint16[] tokenIdsForPrice
returns: uint256
withdraw 0xf940e385
address user
address token
Token Balances (5)
View Transfers →Recent Transactions
No transactions found for this address