Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xf55186CC537E7067EA616F2aaE007b4427a120C8
Balance 0 ETH
Nonce 1
Code Size 23802 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

23802 bytes
0x608060405234801561001057600080fd5b50600436106103925760003560e060020a9004806377274ff0116101e2578063caaa3ada11610113578063f2fde38b116100b1578063fd496ebf11610080578063fd496ebf14611191578063fe5b38e4146111cd578063fe93620e146111d5578063fef3ee73146112b057610392565b8063f2fde38b1461112f578063f3fef3a314611155578063f7e80e9814611181578063fbfa77cf1461118957610392565b8063de30f6ee116100ed578063de30f6ee14610fd5578063e131243e14611011578063e2523632146110d3578063ea466061146110f957610392565b8063caaa3ada14610ecc578063d031256114610fa7578063d913d4e114610faf57610392565b80639303b16f11610180578063a57de4cf1161015a578063a57de4cf14610d60578063a782132c14610d8c578063c19d93fb14610db8578063ca1ce8ce14610dfd57610392565b80639303b16f14610cf7578063a063246114610d14578063a2c9eb6d14610d3a57610392565b80637c68561f116101bc5780637c68561f14610c7f578063867904b414610cbb5780638da5cb5b14610ce75780638f32d59b14610cef57610392565b806377274ff014610c1b57806378446bc114610c415780637add12a614610c4957610392565b80634b37c73f116102c75780635990ca08116102655780636e667db3116102345780636e667db314610bb7578063715018a614610bbf57806372bedcee14610bc757806373088bf714610be557610392565b80635990ca08146109e957806359e026f714610a255780635c21711414610a5b5780635e63349814610b9157610392565b8063539f70d8116102a1578063539f70d8146108aa578063559ed339146108ca57806355d2d9cd146108d257806356fe2784146109ad57610392565b80634b37c73f1461078257806350528ec5146107a857806352a5ce53146107d757610392565b80631ed86f191161033457806330a907361161030e57806330a907361461059f57806334650cd7146106615780633795d9451461073057806347e7ef241461075657610392565b80631ed86f19146104fb57806321a8c1771461052157806329ce1ec51461057957610392565b80631766486d116103705780631766486d1461043e578063186babb21461046d5780631c2a0e40146104935780631e9a6950146104cf57610392565b80630e1fd334146103975780630e4355d4146103d55780630ed09d501461040f575b600080fd5b6103d3600480360360808110156103ad57600080fd5b50600160a060020a038135811691602081013582169160408201351690606001356112d6565b005b6103fb600480360360208110156103eb57600080fd5b5035600160a060020a0316611378565b604080519115158252519081900360200190f35b6103d36004803603604081101561042557600080fd5b50803560ff169060200135600160a060020a0316611396565b61045b6004803603602081101561045457600080fd5b50356114d5565b60408051918252519081900360200190f35b6103d36004803603602081101561048357600080fd5b5035600160a060020a03166114e7565b6103d3600480360360808110156104a957600080fd5b50600160a060020a0381358116916020810135909116906040810135906060013561160f565b6103d3600480360360408110156104e557600080fd5b50600160a060020a038135169060200135611a87565b6103d36004803603602081101561051157600080fd5b5035600160a060020a0316611ab1565b610529611dcf565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561056557818101518382015260200161054d565b505050509050019250505060405180910390f35b6103d36004803603602081101561058f57600080fd5b5035600160a060020a0316611e35565b6103d3600480360360408110156105b557600080fd5b8101906020810181356401000000008111156105d057600080fd5b8201836020820111156105e257600080fd5b8035906020019184602083028401116401000000008311171561060457600080fd5b91939092909160208101903564010000000081111561062257600080fd5b82018360208201111561063457600080fd5b8035906020019184602083028401116401000000008311171561065657600080fd5b509092509050612152565b6103d36004803603606081101561067757600080fd5b81019060208101813564010000000081111561069257600080fd5b8201836020820111156106a457600080fd5b803590602001918460208302840111640100000000831117156106c657600080fd5b91939092600160a060020a03833516926040810190602001356401000000008111156106f157600080fd5b82018360208201111561070357600080fd5b8035906020019184602083028401116401000000008311171561072557600080fd5b509092509050612223565b6103d36004803603602081101561074657600080fd5b5035600160a060020a0316612306565b6103d36004803603604081101561076c57600080fd5b50600160a060020a038135169060200135612417565b6103d36004803603602081101561079857600080fd5b5035600160a060020a03166125a6565b6103d3600480360360408110156107be57600080fd5b50803560ff169060200135600160a060020a03166126b7565b6103d3600480360360808110156107ed57600080fd5b81019060208101813564010000000081111561080857600080fd5b82018360208201111561081a57600080fd5b8035906020019184602083028401116401000000008311171561083c57600080fd5b91939092909160208101903564010000000081111561085a57600080fd5b82018360208201111561086c57600080fd5b8035906020019184602083028401116401000000008311171561088e57600080fd5b9193509150600160a060020a03813581169160200135166129fa565b6103d3600480360360208110156108c057600080fd5b503560ff16612afd565b610529612bd5565b6103d3600480360360808110156108e857600080fd5b81019060208101813564010000000081111561090357600080fd5b82018360208201111561091557600080fd5b8035906020019184602083028401116401000000008311171561093757600080fd5b91939092600160a060020a038335811693602081013590911692919060608101906040013564010000000081111561096e57600080fd5b82018360208201111561098057600080fd5b803590602001918460208302840111640100000000831117156109a257600080fd5b509092509050612c38565b6109cd600480360360208110156109c357600080fd5b503560ff16612d1c565b60408051600160a060020a039092168252519081900360200190f35b6103d3600480360360808110156109ff57600080fd5b50600160a060020a03813581169160208101358216916040820135169060600135612d3a565b6103d360048036036060811015610a3b57600080fd5b50600160a060020a03813581169160208101359091169060400135612d54565b6109cd600480360360e0811015610a7157600080fd5b600160a060020a038235169190810190604081016020820135640100000000811115610a9c57600080fd5b820183602082011115610aae57600080fd5b80359060200191846020830284011164010000000083111715610ad057600080fd5b919390929091602081019035640100000000811115610aee57600080fd5b820183602082011115610b0057600080fd5b80359060200191846020830284011164010000000083111715610b2257600080fd5b919390928235926020810135926040820135929091608081019060600135640100000000811115610b5257600080fd5b820183602082011115610b6457600080fd5b80359060200191846001830284011164010000000083111715610b8657600080fd5b509092509050612e4e565b6103fb60048036036020811015610ba757600080fd5b5035600160a060020a0316613156565b6109cd613174565b6103d3613188565b610bcf6131e3565b6040805160ff9092168252519081900360200190f35b6103d360048036036060811015610bfb57600080fd5b50600160a060020a038135811691602081013590911690604001356131ec565b6103d360048036036020811015610c3157600080fd5b5035600160a060020a0316613211565b61045b613337565b6103d360048036036060811015610c5f57600080fd5b50600160a060020a0381358116916020810135909116906040013561333d565b6103d360048036036080811015610c9557600080fd5b50600160a060020a03813581169160208101358216916040820135169060600135613350565b6103d360048036036040811015610cd157600080fd5b50600160a060020a038135169060200135613364565b6109cd61337b565b6103fb61338a565b6103d360048036036020811015610d0d57600080fd5b503561339b565b6103d360048036036020811015610d2a57600080fd5b5035600160a060020a03166133f4565b6103fb60048036036020811015610d5057600080fd5b5035600160a060020a0316613505565b6103d360048036036040811015610d7657600080fd5b50600160a060020a038135169060200135613523565b6103d360048036036040811015610da257600080fd5b50600160a060020a038135169060200135613539565b610dc06135ed565b6040805160ff9096168652600160a060020a0394851660208701529284168584015290831660608501529091166080830152519081900360a00190f35b6103d360048036036060811015610e1357600080fd5b810190602081018135640100000000811115610e2e57600080fd5b820183602082011115610e4057600080fd5b80359060200191846020830284011164010000000083111715610e6257600080fd5b91939092600160a060020a0383351692604081019060200135640100000000811115610e8d57600080fd5b820183602082011115610e9f57600080fd5b80359060200191846020830284011164010000000083111715610ec157600080fd5b509092509050613619565b6103d360048036036080811015610ee257600080fd5b600160a060020a038235811692602081013590911691810190606081016040820135640100000000811115610f1657600080fd5b820183602082011115610f2857600080fd5b80359060200191846020830284011164010000000083111715610f4a57600080fd5b919390929091602081019035640100000000811115610f6857600080fd5b820183602082011115610f7a57600080fd5b80359060200191846020830284011164010000000083111715610f9c57600080fd5b5090925090506136f3565b61052961376a565b6103fb60048036036020811015610fc557600080fd5b5035600160a060020a03166137cd565b6103d360048036036080811015610feb57600080fd5b50600160a060020a038135811691602081013582169160408201351690606001356137eb565b6103d36004803603604081101561102757600080fd5b81019060208101813564010000000081111561104257600080fd5b82018360208201111561105457600080fd5b8035906020019184602083028401116401000000008311171561107657600080fd5b91939092909160208101903564010000000081111561109457600080fd5b8201836020820111156110a657600080fd5b803590602001918460208302840111640100000000831117156110c857600080fd5b509092509050613885565b6103d3600480360360208110156110e957600080fd5b5035600160a060020a0316613900565b6103d36004803603606081101561110f57600080fd5b50600160a060020a03813581169160208101359091169060400135613c1d565b6103d36004803603602081101561114557600080fd5b5035600160a060020a0316613c34565b6103d36004803603604081101561116b57600080fd5b50600160a060020a038135169060200135613c4e565b610529613d67565b6109cd613dca565b6103d3600480360360808110156111a757600080fd5b50600160a060020a03813581169160208101359160408201358116916060013516613dd9565b610529613e7d565b6103d3600480360360808110156111eb57600080fd5b600160a060020a03823581169260208101359091169181019060608101604082013564010000000081111561121f57600080fd5b82018360208201111561123157600080fd5b8035906020019184602083028401116401000000008311171561125357600080fd5b91939092909160208101903564010000000081111561127157600080fd5b82018360208201111561128357600080fd5b803590602001918460208302840111640100000000831117156112a557600080fd5b509092509050613ee0565b6103fb600480360360208110156112c657600080fd5b5035600160a060020a0316613f57565b6112de613f75565b60408051600180825281830190925260609160208083019080388339019050509050828160008151811061130e57fe5b600160a060020a0390921660209283029190910190910152604080516001808252818301909252606091816020016020820280388339019050509050828160008151811061135857fe5b60200260200101818152505061137086868484613fde565b505050505050565b600160a060020a031660009081526007602052604090205460ff1690565b61139e61338a565b6113a757600080fd5b60ff8216600090815260056020526040902054600160a060020a0316158015906113ee575060ff8216600090815260056020526040902054600160a060020a038281169116145b6113f757600080fd5b611467816001600d0180548060200260200160405190810160405280929190818152602001828054801561145457602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611436575b505050505061438190919063ffffffff16565b805161147b91600e91602090910190615b77565b5060ff82166000818152600560209081526040918290208054600160a060020a0319169055815192835290517f42116f6ac93a703960c38868360efe785bcbde597f6abff4118ab7acb63d5e2b9281900390910190a15050565b60126020526000908152604090205481565b6114ef61338a565b6114f857600080fd5b600160a060020a0381166000908152600a602052604090205460ff1661151d57600080fd5b61158d816001600a0180548060200260200160405190810160405280929190818152602001828054801561157a57602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161155c575b50505050506143bc90919063ffffffff16565b80516115a191600b91602090910190615b77565b50600160a060020a0381166000818152600960209081526040808320805460ff19908116600117909155600a8352928190208054909316909255815192835290517f8d74f17aca5cfe232ba80fa74b1836e0d7aafe0e1e7cc161403a9a4126a26b9a9281900390910190a150565b6010805460010190819055606061162786338661446b565b9050606080735f3f534d0c5ea126150ec8078d404464339503ca635720a5d984876040518363ffffffff1660e060020a0281526004018080602001838152602001828103825284818151815260200191508051906020019060200280838360005b838110156116a0578181015183820152602001611688565b50505050905001935050505060006040518083038186803b1580156116c457600080fd5b505af41580156116d8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561170157600080fd5b81019080805164010000000081111561171957600080fd5b8201602081018481111561172c57600080fd5b815185602082028301116401000000008211171561174957600080fd5b5050929190602001805164010000000081111561176557600080fd5b8201602081018481111561177857600080fd5b815185602082028301116401000000008211171561179557600080fd5b50509291905050508092508193505050606088600160a060020a03166399d50d5d6040518163ffffffff1660e060020a02815260040160006040518083038186803b1580156117e357600080fd5b505afa1580156117f7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561182057600080fd5b81019080805164010000000081111561183857600080fd5b8201602081018481111561184b57600080fd5b815185602082028301116401000000008211171561186857600080fd5b50506004805460405160e060020a6312a3bbe3028152600160a060020a038f81166024830152606093820193845284516064830152845194985090911695506312a3bbe394508693508d9289929182916044820191608401906020808901910280838360005b838110156118e65781810151838201526020016118ce565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561192557818101518382015260200161190d565b5050505090500195505050505050600060405180830381600087803b15801561194d57600080fd5b505af1158015611961573d6000803e3d6000fd5b5050600480546040517f2321af6a000000000000000000000000000000000000000000000000000000008152600160a060020a038d81166024830152606093820193845286516064830152865192169450632321af6a935085928d92889282916044820191608401906020808901910280838360005b838110156119ef5781810151838201526020016119d7565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015611a2e578181015183820152602001611a16565b5050505090500195505050505050600060405180830381600087803b158015611a5657600080fd5b505af1158015611a6a573d6000803e3d6000fd5b50505050505050506010548114611a8057600080fd5b5050505050565b6010805460010190819055611a9e33808585614892565b6010548114611aac57600080fd5b505050565b611ab961338a565b611ac257600080fd5b601154611bd357600160a060020a03811660009081526006602052604090205460ff1615611aef57600080fd5b600160a060020a038116600090815260066020908152604091829020805460ff19166001179055600c8054835181840281018401909452808452611b7d9385939092919083018282801561157a57602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161155c5750505050506143bc90919063ffffffff16565b8051611b9191600c91602090910190615b77565b5060408051600160a060020a038316815290517fead6a006345da1073a106d5f32372d2d2204f46cb0b4bca8f5ebafcbbed12b8a9181900360200190a1611dcc565b60008036604051602001808383808284376040805191909301818103601f1901825283528051602091820120600081815260129092529290205491955090935050508115159050611c605760008281526012602090815260409182902042908190558251858152918201528151600080516020615caf833981519152929181900390910190a15050611dcc565b601154611c7490829063ffffffff614a4916565b421015611cb55760405160e560020a62461bcd028152600401808060200182810382526034815260200180615c426034913960400191505060405180910390fd5b6000828152601260209081526040808320839055600160a060020a0386168352600690915290205460ff1615611cea57600080fd5b600160a060020a038316600090815260066020908152604091829020805460ff19166001179055600c8054835181840281018401909452808452611d789387939092919083018282801561157a57602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161155c5750505050506143bc90919063ffffffff16565b8051611d8c91600c91602090910190615b77565b5060408051600160a060020a038516815290517fead6a006345da1073a106d5f32372d2d2204f46cb0b4bca8f5ebafcbbed12b8a9181900360200190a150505b50565b60606001600d01805480602002602001604051908101604052809291908181526020018280548015611e2a57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611e0c575b505050505090505b90565b611e3d61338a565b611e4657600080fd5b601154611f5757600160a060020a03811660009081526007602052604090205460ff1615611e7357600080fd5b600160a060020a038116600090815260076020908152604091829020805460ff19166001179055600d8054835181840281018401909452808452611f019385939092919083018282801561157a57602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161155c5750505050506143bc90919063ffffffff16565b8051611f1591600d91602090910190615b77565b5060408051600160a060020a038316815290517f6fdc0147105e43e21da80a75b42d0fd464060d5e1a34b0cefbf0b4ccfc2e36a19181900360200190a1611dcc565b60008036604051602001808383808284376040805191909301818103601f1901825283528051602091820120600081815260129092529290205491955090935050508115159050611fe45760008281526012602090815260409182902042908190558251858152918201528151600080516020615caf833981519152929181900390910190a15050611dcc565b601154611ff890829063ffffffff614a4916565b4210156120395760405160e560020a62461bcd028152600401808060200182810382526034815260200180615c426034913960400191505060405180910390fd5b6000828152601260209081526040808320839055600160a060020a0386168352600790915290205460ff161561206e57600080fd5b600160a060020a038316600090815260076020908152604091829020805460ff19166001179055600d80548351818402810184019094528084526120fc9387939092919083018282801561157a57602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161155c5750505050506143bc90919063ffffffff16565b805161211091600d91602090910190615b77565b5060408051600160a060020a038516815290517f6fdc0147105e43e21da80a75b42d0fd464060d5e1a34b0cefbf0b4ccfc2e36a19181900360200190a1505050565b601080546001908101918290555460ff16156121a6576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615c22833981519152604482015290519081900360640190fd5b612215333387878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250614a6292505050565b6010548114611a8057600080fd5b61222b613f75565b6004805460405160e060020a6312a3bbe3028152600160a060020a038681166024830152606093820193845260648201889052909116916312a3bbe391889188918891889188919081906044810190608401886020890280828437600083820152601f01601f19169091018481038352858152602090810191508690860280828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b1580156122e757600080fd5b505af11580156122fb573d6000803e3d6000fd5b505050505050505050565b61230e61338a565b61231757600080fd5b600160a060020a03811660009081526008602052604090205460ff1661233c57600080fd5b6123aa816001600e0180548060200260200160405190810160405280929190818152602001828054801561145457602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161143657505050505061438190919063ffffffff16565b80516123be91600f91602090910190615b77565b50600160a060020a038116600081815260086020908152604091829020805460ff19169055815192835290517f12659d0b4b2995d3c080d94902544375948e4a831f1b64271c7de762ae21534d9281900390910190a150565b601080546001908101918290555460ff161561246b576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615c22833981519152604482015290519081900360640190fd5b8115611a9e57600354600254604080517fa6c4e467000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301526024820187905233604483015292831660648201529051919092169163a6c4e46791608480830192600092919082900301818387803b1580156124f057600080fd5b505af1158015612504573d6000803e3d6000fd5b505060048054604080517fbada5726000000000000000000000000000000000000000000000000000000008152600160a060020a038981169482019490945233602482015260448101889052905192909116935063bada5726925060648082019260009290919082900301818387803b15801561258057600080fd5b505af1158015612594573d6000803e3d6000fd5b505050506010548114611aac57600080fd5b6125ae61338a565b6125b757600080fd5b600160a060020a03811660009081526007602052604090205460ff166125dc57600080fd5b61264a816001600c0180548060200260200160405190810160405280929190818152602001828054801561145457602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161143657505050505061438190919063ffffffff16565b805161265e91600d91602090910190615b77565b50600160a060020a038116600081815260076020908152604091829020805460ff19169055815192835290517fafa2737b2090fa39c66b7348625f0c03726240f724defbc6216d679506f944419281900390910190a150565b6126bf61338a565b6126c857600080fd5b6011546127eb5760ff8216600090815260056020526040902054600160a060020a0316156126f557600080fd5b60ff82166000908152600560209081526040918290208054600160a060020a031916600160a060020a038516179055600e805483518184028101840190945280845261278b9385939092919083018282801561157a57602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161155c5750505050506143bc90919063ffffffff16565b805161279f91600e91602090910190615b77565b506040805160ff84168152600160a060020a038316602082015281517f5af656389b2b10b228bd4cf78dfb8d62944a8847285a93d5e976698ff69c61c4929181900390910190a16129f6565b60008036604051602001808383808284376040805191909301818103601f19018252835280516020918201206000818152601290925292902054919550909350505081151590506128785760008281526012602090815260409182902042908190558251858152918201528151600080516020615caf833981519152929181900390910190a150506129f6565b60115461288c90829063ffffffff614a4916565b4210156128cd5760405160e560020a62461bcd028152600401808060200182810382526034815260200180615c426034913960400191505060405180910390fd5b600082815260126020908152604080832083905560ff871683526005909152902054600160a060020a03161561290257600080fd5b60ff84166000908152600560209081526040918290208054600160a060020a031916600160a060020a038716179055600e80548351818402810184019094528084526129989387939092919083018282801561157a57602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161155c5750505050506143bc90919063ffffffff16565b80516129ac91600e91602090910190615b77565b506040805160ff86168152600160a060020a038516602082015281517f5af656389b2b10b228bd4cf78dfb8d62944a8847285a93d5e976698ff69c61c4929181900390910190a150505b5050565b612a02613f75565b6003546040517f709a385e000000000000000000000000000000000000000000000000000000008152600160a060020a03848116604483015283811660648301526080600483019081526084830189905292169163709a385e918991899189918991899189918190602481019060a4018960208a0280828437600083820152601f01601f19169091018481038352878152602090810191508890880280828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015612add57600080fd5b505af1158015612af1573d6000803e3d6000fd5b50505050505050505050565b612b0561338a565b612b0e57600080fd5b600260ff8216108015612b29575060015460ff828116911614155b612b7d576040805160e560020a62461bcd02815260206004820152601560248201527f496e76616c69644f7065726174696f6e53746174650000000000000000000000604482015290519081900360640190fd5b6001546040805160ff9283168152918316602083015280517f64d299fbc729d870a19dc650c5bc71264299611e5919111b23c981262c402e6a9281900390910190a16001805460ff191660ff92909216919091179055565b60606001600a01805480602002602001604051908101604052809291908181526020018280548015611e2a57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311611e0c575050505050905090565b612c40613f75565b600480546040517f20153c38000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660248301528681166044830152608093820193845260848201899052909116916320153c38918991899189918991899189918190606481019060a4018960208a0280828437600083820152601f01601f19169091018481038352858152602090810191508690860280828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b158015612add57600080fd5b60ff16600090815260056020526040902054600160a060020a031690565b612d42613f75565b612d4e84848484614892565b50505050565b601080546001908101918290555460ff1615612da8576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615c22833981519152604482015290519081900360640190fd5b60048054604080517fb19ad577000000000000000000000000000000000000000000000000000000008152600160a060020a03888116948201949094523360248201528684166044820152606481018690529051929091169163b19ad5779160848082019260009290919082900301818387803b158015612e2857600080fd5b505af1158015612e3c573d6000803e3d6000fd5b505050506010548114612d4e57600080fd5b600160a060020a038a1660009081526007602052604081205460ff16612ebe576040805160e560020a62461bcd02815260206004820152600960248201527f4372656174655365740000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60008b600160a060020a031663569f74948c8c8c8c8c8c8c8c8c6040518a63ffffffff1660e060020a0281526004018080602001806020018881526020018781526020018681526020018060200184810384528d8d82818152602001925060200280828437600083820152601f01601f191690910185810384528b8152602090810191508c908c0280828437600083820152601f01601f191690910185810383528681526020019050868680828437600081840152601f19601f8201169050808301925050509c50505050505050505050505050602060405180830381600087803b158015612fac57600080fd5b505af1158015612fc0573d6000803e3d6000fd5b505050506040513d6020811015612fd657600080fd5b81019080805190602001909291905050509050600180600801600083600160a060020a0316600160a060020a0316815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600a018190806001815401808255809150509060018203906000526020600020016000909192909190916101000a815481600160a060020a030219169083600160a060020a031602179055505080600160a060020a03167fa31e381e140096a837a20ba16eb64e32a4011fda0697adbfd7a8f7341c56aa948d8d8d8d8d8d8d8d6040518089600160a060020a0316600160a060020a03168152602001806020018060200186815260200185815260200184815260200183810383528a8a82818152602001925060200280828437600083820152601f01601f19169091018481038352888152602090810191508990890280828437600083820152604051601f909101601f19169092018290039c50909a5050505050505050505050a29b9a5050505050505050505050565b600160a060020a031660009081526006602052604090205460ff1690565b6001546101009004600160a060020a031690565b61319061338a565b61319957600080fd5b60008054604051600160a060020a03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360008054600160a060020a0319169055565b60015460ff1690565b601080546001019081905561320333858585614dde565b6010548114612d4e57600080fd5b61321961338a565b61322257600080fd5b600160a060020a03811660009081526009602052604090205460ff1661324757600080fd5b6132b5816001600a0180548060200260200160405190810160405280929190818152602001828054801561145457602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161143657505050505061438190919063ffffffff16565b80516132c991600b91602090910190615b77565b50600160a060020a0381166000818152600960209081526040808320805460ff19908116909155600a8352928190208054909316600117909255815192835290517fda03368896dbc730fed10cdf94837def8f7a9ce04e2fe795e3331b9b2f3b680f9281900390910190a150565b60115481565b613345613f75565b611aac8383836156a9565b613358613f75565b612d4e84848484614dde565b6010805460010190819055611a9e33808585614dde565b600054600160a060020a031690565b600054600160a060020a0316331490565b6133a361338a565b6133ac57600080fd5b60115481116133ef5760405160e560020a62461bcd028152600401808060200182810382526039815260200180615c766039913960400191505060405180910390fd5b601155565b6133fc61338a565b61340557600080fd5b600160a060020a03811660009081526006602052604090205460ff1661342a57600080fd5b613498816001600b0180548060200260200160405190810160405280929190818152602001828054801561145457602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161143657505050505061438190919063ffffffff16565b80516134ac91600c91602090910190615b77565b50600160a060020a038116600081815260066020908152604091829020805460ff19169055815192835290517f0a1ee69f55c33d8467c69ca59ce2007a737a88603d75392972520bf67cb513b89281900390910190a150565b600160a060020a031660009081526008602052604090205460ff1690565b6010805460010190819055611a9e3384846156a9565b601080546001019081905560048054604080517f80ddda30000000000000000000000000000000000000000000000000000000008152600160a060020a038781169482019490945233602482015260448101869052905192909116916380ddda309160648082019260009290919082900301818387803b1580156135bc57600080fd5b505af11580156135d0573d6000803e3d6000fd5b5050600254611a9e9250600160a060020a03169050338585614892565b60015460025460035460045460ff841693600160a060020a036101009091048116938116928116911685565b613621613f75565b600480546040517f3911477c000000000000000000000000000000000000000000000000000000008152600160a060020a03868116602483015260609382019384526064820188905290911691633911477c91889188918891889188919081906044810190608401886020890280828437600083820152601f01601f19169091018481038352858152602090810191508690860280828437600081840152601f19601f820116905080830192505050975050505050505050600060405180830381600087803b1580156122e757600080fd5b6136fb613f75565b611370868686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092019190915250614a6292505050565b60606001600e01805480602002602001604051908101604052809291908181526020018280548015611e2a57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311611e0c575050505050905090565b600160a060020a03166000908152600a602052604090205460ff1690565b6137f3613f75565b60408051600180825281830190925260609160208083019080388339019050509050828160008151811061382357fe5b600160a060020a0390921660209283029190910190910152604080516001808252818301909252606091816020016020820280388339019050509050828160008151811061386d57fe5b60200260200101818152505061137086868484614a62565b60108054600101908190556040805160208087028281018201909352868252612215923392839290918a918a91829185019084908082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250613fde92505050565b61390861338a565b61391157600080fd5b601154613a2257600160a060020a03811660009081526008602052604090205460ff161561393e57600080fd5b600160a060020a038116600090815260086020908152604091829020805460ff19166001179055600f80548351818402810184019094528084526139cc9385939092919083018282801561157a57602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161155c5750505050506143bc90919063ffffffff16565b80516139e091600f91602090910190615b77565b5060408051600160a060020a038316815290517f48d0af0a381b9ea5058d3a9a871e53204fa4813bb6ae0fca043f0cb7f1b7acee9181900360200190a1611dcc565b60008036604051602001808383808284376040805191909301818103601f1901825283528051602091820120600081815260129092529290205491955090935050508115159050613aaf5760008281526012602090815260409182902042908190558251858152918201528151600080516020615caf833981519152929181900390910190a15050611dcc565b601154613ac390829063ffffffff614a4916565b421015613b045760405160e560020a62461bcd028152600401808060200182810382526034815260200180615c426034913960400191505060405180910390fd5b6000828152601260209081526040808320839055600160a060020a0386168352600890915290205460ff1615613b3957600080fd5b600160a060020a038316600090815260086020908152604091829020805460ff19166001179055600f8054835181840281018401909452808452613bc79387939092919083018282801561157a57602002820191906000526020600020908154600160a060020a0316815260019091019060200180831161155c5750505050506143bc90919063ffffffff16565b8051613bdb91600f91602090910190615b77565b5060408051600160a060020a038516815290517f48d0af0a381b9ea5058d3a9a871e53204fa4813bb6ae0fca043f0cb7f1b7acee9181900360200190a1505050565b601080546001019081905561320333858585614892565b613c3c61338a565b613c4557600080fd5b611dcc81615759565b60108054600101908190558115611a9e5760048054604080517f80ddda30000000000000000000000000000000000000000000000000000000008152600160a060020a038781169482019490945233602482015260448101869052905192909116916380ddda309160648082019260009290919082900301818387803b158015613cd757600080fd5b505af1158015613ceb573d6000803e3d6000fd5b505060048054604080517fc3b35a7e000000000000000000000000000000000000000000000000000000008152600160a060020a038981169482019490945233602482015260448101889052905192909116935063c3b35a7e925060648082019260009290919082900301818387803b15801561258057600080fd5b60606001600b01805480602002602001604051908101604052809291908181526020018280548015611e2a57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311611e0c575050505050905090565b600254600160a060020a031690565b613de1613f75565b600354604080517fa6c4e467000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015260248201879052858116604483015284811660648301529151919092169163a6c4e46791608480830192600092919082900301818387803b158015613e5f57600080fd5b505af1158015613e73573d6000803e3d6000fd5b5050505050505050565b60606001600c01805480602002602001604051908101604052809291908181526020018280548015611e2a57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311611e0c575050505050905090565b613ee8613f75565b611370868686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092019190915250613fde92505050565b600160a060020a031660009081526009602052604090205460ff1690565b3360009081526006602052604090205460ff16613fdc576040805160e560020a62461bcd02815260206004820152600a60248201527f4f6e6c794d6f64756c6500000000000000000000000000000000000000000000604482015290519081900360640190fd5b565b6040517f64cf166f00000000000000000000000000000000000000000000000000000000815260206004820181815284516024840152845173c269e9396556b6afb0c38eef4a590321ff9e8d3a936364cf166f93879392839260440191808601910280838360005b8381101561405e578181015183820152602001614046565b505050509050019250505060006040518083038186803b15801561408157600080fd5b505af4158015614095573d6000803e3d6000fd5b5050505073c269e9396556b6afb0c38eef4a590321ff9e8d3a632c183f4383836040518363ffffffff1660e060020a028152600401808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561410b5781810151838201526020016140f3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561414a578181015183820152602001614132565b5050505090500194505050505060006040518083038186803b15801561416f57600080fd5b505af4158015614183573d6000803e3d6000fd5b5050600480546040517f3911477c000000000000000000000000000000000000000000000000000000008152600160a060020a038981166024830152606093820193845287516064830152875192169450633911477c935086928992879282916044820191608401906020808901910280838360005b838110156142115781810151838201526020016141f9565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015614250578181015183820152602001614238565b5050505090500195505050505050600060405180830381600087803b15801561427857600080fd5b505af115801561428c573d6000803e3d6000fd5b5050600480546040517f2321af6a000000000000000000000000000000000000000000000000000000008152600160a060020a038881166024830152606093820193845287516064830152875192169450632321af6a935086928892879282916044820191608401906020808901910280838360005b8381101561431a578181015183820152602001614302565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015614359578181015183820152602001614341565b5050505090500195505050505050600060405180830381600087803b158015613e5f57600080fd5b606060008061439085856157c7565b915091508061439e57600080fd5b60606143aa868461582b565b5093506143b692505050565b92915050565b60608083516001016040519080825280602002602001820160405280156143ed578160200160208202803883390190505b50905060005b845181101561443c5784818151811061440857fe5b602002602001015182828151811061441c57fe5b600160a060020a03909216602092830291909101909101526001016143f3565b50828185518151811061444b57fe5b600160a060020a0390921660209283029190910190910152905092915050565b600160a060020a03831660009081526009602052604090205460609060ff166144de576040805160e560020a62461bcd02815260206004820152601760248201527f52656465656d416e6444656372656d656e745661756c74000000000000000000604482015290519081900360640190fd5b604080517f49468457000000000000000000000000000000000000000000000000000000008152600160a060020a038616600482015260248101849052905173dc733ec262f32882f7c05525cc2d09f2c04d86ac916349468457916044808301926000929190829003018186803b15801561455857600080fd5b505af415801561456c573d6000803e3d6000fd5b5050505083600160a060020a0316639dc29fac84846040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b1580156145d357600080fd5b505af11580156145e7573d6000803e3d6000fd5b505050506145f3615bdc565b6145fc85615925565b90506060735f3f534d0c5ea126150ec8078d404464339503ca636cc34bcc83604001518460000151876040518463ffffffff1660e060020a0281526004018080602001848152602001838152602001828103825285818151815260200191508051906020019060200280838360005b8381101561468357818101518382015260200161466b565b5050505090500194505050505060006040518083038186803b1580156146a857600080fd5b505af41580156146bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156146e557600080fd5b8101908080516401000000008111156146fd57600080fd5b8201602081018481111561471057600080fd5b815185602082028301116401000000008211171561472d57600080fd5b5050600480546020808901516040517f3911477c000000000000000000000000000000000000000000000000000000008152600160a060020a038f811660248301526060958201958652825160648301528251969a509093169750633911477c965094508c9388939283926044820192608490920191888201910280838360005b838110156147c65781810151838201526020016147ae565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156148055781810151838201526020016147ed565b5050505090500195505050505050600060405180830381600087803b15801561482d57600080fd5b505af1158015614841573d6000803e3d6000fd5b505060408051600160a060020a038a1681526020810188905281517f91890c0c52be4f9408213391452e5480eaff0e6ab6e4cbf17cde754f911de5359450908190039091019150a195945050505050565b606061489f83868461446b565b9050606083600160a060020a03166399d50d5d6040518163ffffffff1660e060020a02815260040160006040518083038186803b1580156148df57600080fd5b505afa1580156148f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561491c57600080fd5b81019080805164010000000081111561493457600080fd5b8201602081018481111561494757600080fd5b815185602082028301116401000000008211171561496457600080fd5b50506004805460405160e060020a6312a3bbe3028152600160a060020a038c81166024830152606093820193845284516064830152845194985090911695506312a3bbe394508693508a9288929182916044820191608401906020808901910280838360005b838110156149e25781810151838201526020016149ca565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015614a21578181015183820152602001614a09565b5050505090500195505050505050600060405180830381600087803b158015612add57600080fd5b600082820183811015614a5b57600080fd5b9392505050565b60015460ff1615614aab576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615c22833981519152604482015290519081900360640190fd5b6040517f64cf166f00000000000000000000000000000000000000000000000000000000815260206004820181815284516024840152845173c269e9396556b6afb0c38eef4a590321ff9e8d3a936364cf166f93879392839260440191808601910280838360005b83811015614b2b578181015183820152602001614b13565b505050509050019250505060006040518083038186803b158015614b4e57600080fd5b505af4158015614b62573d6000803e3d6000fd5b5050505073c269e9396556b6afb0c38eef4a590321ff9e8d3a632c183f4383836040518363ffffffff1660e060020a028152600401808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015614bd8578181015183820152602001614bc0565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015614c17578181015183820152602001614bff565b5050505090500194505050505060006040518083038186803b158015614c3c57600080fd5b505af4158015614c50573d6000803e3d6000fd5b50506003546002546040517f709a385e000000000000000000000000000000000000000000000000000000008152600160a060020a0389811660448301529182166064820181905260806004830190815288516084840152885193909416955063709a385e9450879387938b938291602482019160a401906020808a01910280838360005b83811015614ced578181015183820152602001614cd5565b50505050905001838103825286818151815260200191508051906020019060200280838360005b83811015614d2c578181015183820152602001614d14565b505050509050019650505050505050600060405180830381600087803b158015614d5557600080fd5b505af1158015614d69573d6000803e3d6000fd5b50506004805460405160e060020a6312a3bbe3028152600160a060020a0388811660248301526060938201938452875160648301528751921694506312a3bbe393508692889287928291604482019160840190602088810191028083836000831561431a578181015183820152602001614302565b60015460ff1615614e27576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615c22833981519152604482015290519081900360640190fd5b600160a060020a03821660009081526009602052604090205460ff16614e97576040805160e560020a62461bcd02815260206004820152600d60248201527f4973737565496e7465726e616c00000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f49468457000000000000000000000000000000000000000000000000000000008152600160a060020a038416600482015260248101839052905173dc733ec262f32882f7c05525cc2d09f2c04d86ac916349468457916044808301926000929190829003018186803b158015614f1157600080fd5b505af4158015614f25573d6000803e3d6000fd5b50505050614f31615bdc565b614f3a83615925565b90506060735f3f534d0c5ea126150ec8078d404464339503ca636cc34bcc83604001518460000151866040518463ffffffff1660e060020a0281526004018080602001848152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015614fc1578181015183820152602001614fa9565b5050505090500194505050505060006040518083038186803b158015614fe657600080fd5b505af4158015614ffa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561502357600080fd5b81019080805164010000000081111561503b57600080fd5b8201602081018481111561504e57600080fd5b815185602082028301116401000000008211171561506b57600080fd5b50509291905050509050606080735f3f534d0c5ea126150ec8078d404464339503ca639b9f5c938560200151858b6001800160009054906101000a9004600160a060020a03166040518563ffffffff1660e060020a02815260040180806020018060200185600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a03168152602001838103835287818151815260200191508051906020019060200280838360005b8381101561513757818101518382015260200161511f565b50505050905001838103825286818151815260200191508051906020019060200280838360005b8381101561517657818101518382015260200161515e565b50505050905001965050505050505060006040518083038186803b15801561519d57600080fd5b505af41580156151b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160409081528110156151da57600080fd5b8101908080516401000000008111156151f257600080fd5b8201602081018481111561520557600080fd5b815185602082028301116401000000008211171561522257600080fd5b5050929190602001805164010000000081111561523e57600080fd5b8201602081018481111561525157600080fd5b815185602082028301116401000000008211171561526e57600080fd5b50509291905050508092508193505050600160030160009054906101000a9004600160a060020a0316600160a060020a0316633911477c85602001518a856040518463ffffffff1660e060020a028152600401808060200184600160a060020a0316600160a060020a0316815260200180602001838103835286818151815260200191508051906020019060200280838360005b8381101561531a578181015183820152602001615302565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015615359578181015183820152602001615341565b5050505090500195505050505050600060405180830381600087803b15801561538157600080fd5b505af1158015615395573d6000803e3d6000fd5b50505050600160020160009054906101000a9004600160a060020a0316600160a060020a031663709a385e8560200151838b6001800160009054906101000a9004600160a060020a03166040518563ffffffff1660e060020a02815260040180806020018060200185600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a03168152602001838103835287818151815260200191508051906020019060200280838360005b8381101561546557818101518382015260200161544d565b50505050905001838103825286818151815260200191508051906020019060200280838360005b838110156154a457818101518382015260200161548c565b505050509050019650505050505050600060405180830381600087803b1580156154cd57600080fd5b505af11580156154e1573d6000803e3d6000fd5b50506004805460208089015160405160e060020a6312a3bbe3028152600160a060020a038d811660248301526060958201958652825160648301528251941696506312a3bbe3955090938c938a93919283926044820192608490920191888201910280838360005b83811015615561578181015183820152602001615549565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156155a0578181015183820152602001615588565b5050505090500195505050505050600060405180830381600087803b1580156155c857600080fd5b505af11580156155dc573d6000803e3d6000fd5b5050505085600160a060020a03166340c10f1988876040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b15801561564357600080fd5b505af1158015615657573d6000803e3d6000fd5b505060408051600160a060020a038a1681526020810189905281517f9c2c6ec1cb8ee2fe8d5549d7d071a1a8f76ec3cc057d7c46f118247b0e5e85729450908190039091019150a15050505050505050565b6002546156c2908490600160a060020a03168484614dde565b60048054604080517fbada5726000000000000000000000000000000000000000000000000000000008152600160a060020a03868116948201949094528684166024820152604481018590529051929091169163bada57269160648082019260009290919082900301818387803b15801561573c57600080fd5b505af1158015615750573d6000803e3d6000fd5b50505050505050565b600160a060020a03811661576c57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360008054600160a060020a031916600160a060020a0392909216919091179055565b81516000908190815b8181101561581a5784600160a060020a03168682815181106157ee57fe5b6020026020010151600160a060020a03161415615812579250600191506158249050565b6001016157d0565b5060009250829150505b9250929050565b606060008084519050606060018203604051908082528060200260200182016040528015615863578160200160208202803883390190505b50905060005b858110156158b15786818151811061587d57fe5b602002602001015182828151811061589157fe5b600160a060020a0390921660209283029190910190910152600101615869565b50600185015b82811015615902578681815181106158cb57fe5b60200260200101518260018303815181106158e257fe5b600160a060020a03909216602092830291909101909101526001016158b7565b508086868151811061591057fe5b60200260200101519350935050509250929050565b61592d615bdc565b6000829050600081600160a060020a03166342a7cfd56040518163ffffffff1660e060020a02815260040160206040518083038186803b15801561597057600080fd5b505afa158015615984573d6000803e3d6000fd5b505050506040513d602081101561599a57600080fd5b5051604080517f99d50d5d0000000000000000000000000000000000000000000000000000000081529051919250606091600160a060020a038516916399d50d5d916004808301926000929190829003018186803b1580156159fb57600080fd5b505afa158015615a0f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015615a3857600080fd5b810190808051640100000000811115615a5057600080fd5b82016020810184811115615a6357600080fd5b8151856020820283011164010000000082111715615a8057600080fd5b50509291905050509050606083600160a060020a031663027aa9f56040518163ffffffff1660e060020a02815260040160006040518083038186803b158015615ac857600080fd5b505afa158015615adc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015615b0557600080fd5b810190808051640100000000811115615b1d57600080fd5b82016020810184811115615b3057600080fd5b8151856020820283011164010000000082111715615b4d57600080fd5b50506040805160608101825297885260208801969096529486019490945250929695505050505050565b828054828255906000526020600020908101928215615bcc579160200282015b82811115615bcc5782518254600160a060020a031916600160a060020a03909116178255602090920191600190910190615b97565b50615bd8929150615bfd565b5090565b60405180606001604052806000815260200160608152602001606081525090565b611e3291905b80821115615bd8578054600160a060020a0319168155600101615c0356fe5768656e4f7065726174696f6e616c000000000000000000000000000000000054696d654c6f636b557067726164653a2054696d65206c6f636b20706572696f64206d757374206861766520656c61707365642e54696d654c6f636b557067726164653a204e657720706572696f64206d7573742062652067726561746572207468616e206578697374696e670e0905d1a972d476e353bdcc3e06b19a71709054c8ba01eccb7e0691eca6d374a165627a7a723058207f66ae1ea5ac4a9a694c92f8f53315e56da7b929e41ec8f5869d23dca00794bf0029

Verified Source Code Partial Match

Compiler: v0.5.7+commit.6da8b019 EVM: byzantium Optimization: Yes (200 runs)
Core.sol 3632 lines
// File: openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol

pragma solidity ^0.5.2;

/**
 * @title Helps contracts guard against reentrancy attacks.
 * @author Remco Bloemen <remco@2π.com>, Eenae <[email protected]>
 * @dev If you mark a function `nonReentrant`, you should also
 * mark it `external`.
 */
contract ReentrancyGuard {
    /// @dev counter to allow mutex lock with only one SSTORE operation
    uint256 private _guardCounter;

    constructor () internal {
        // The counter starts at one to prevent changing it from zero to a non-zero
        // value, which is a more expensive operation.
        _guardCounter = 1;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _guardCounter += 1;
        uint256 localCounter = _guardCounter;
        _;
        require(localCounter == _guardCounter);
    }
}

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

pragma solidity ^0.5.2;

/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error
 */
library SafeMath {
    /**
     * @dev Multiplies two unsigned integers, reverts on 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-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    /**
     * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Adds two unsigned integers, reverts on overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }

    /**
     * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
     * reverts when dividing by zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}

// File: contracts/lib/CommonValidationsLibrary.sol

/*
    Copyright 2018 Set Labs Inc.

    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.5.7;


library CommonValidationsLibrary {

    /**
     * Ensures that an address array is not empty.
     *
     * @param  _addressArray       Address array input
     */
    function validateNonEmpty(
        address[] calldata _addressArray
    )
        external
        pure
    {
        require(
            _addressArray.length > 0,
            "Address array length must be > 0"
        );
    }

    /**
     * Ensures that an address array and uint256 array are equal length
     *
     * @param  _addressArray       Address array input
     * @param  _uint256Array       Uint256 array input
     */
    function validateEqualLength(
        address[] calldata _addressArray,
        uint256[] calldata _uint256Array
    )
        external
        pure
    {
        require(
            _addressArray.length == _uint256Array.length,
            "Input length mismatch"
        );
    }
}

// File: openzeppelin-solidity/contracts/ownership/Ownable.sol

pragma solidity ^0.5.2;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor () internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     * It will not be possible to call the functions with the `onlyOwner`
     * modifier anymore.
     * @notice Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0));
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: contracts/core/interfaces/ITransferProxy.sol

/*
    Copyright 2018 Set Labs Inc.

    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.5.7;

/**
 * @title ITransferProxy
 * @author Set Protocol
 *
 * The ITransferProxy interface provides a light-weight, structured way to interact with the
 * TransferProxy contract from another contract.
 */
interface ITransferProxy {

    /* ============ External Functions ============ */

    /**
     * Transfers tokens from an address (that has set allowance on the proxy).
     * Can only be called by authorized core contracts.
     *
     * @param  _token          The address of the ERC20 token
     * @param  _quantity       The number of tokens to transfer
     * @param  _from           The address to transfer from
     * @param  _to             The address to transfer to
     */
    function transfer(
        address _token,
        uint256 _quantity,
        address _from,
        address _to
    )
        external;

    /**
     * Transfers tokens from an address (that has set allowance on the proxy).
     * Can only be called by authorized core contracts.
     *
     * @param  _tokens         The addresses of the ERC20 token
     * @param  _quantities     The numbers of tokens to transfer
     * @param  _from           The address to transfer from
     * @param  _to             The address to transfer to
     */
    function batchTransfer(
        address[] calldata _tokens,
        uint256[] calldata _quantities,
        address _from,
        address _to
    )
        external;
}

// File: contracts/core/interfaces/IVault.sol

/*
    Copyright 2018 Set Labs Inc.

    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.5.7;

/**
 * @title IVault
 * @author Set Protocol
 *
 * The IVault interface provides a light-weight, structured way to interact with the Vault
 * contract from another contract.
 */
interface IVault {

    /*
     * Withdraws user's unassociated tokens to user account. Can only be
     * called by authorized core contracts.
     *
     * @param  _token          The address of the ERC20 token
     * @param  _to             The address to transfer token to
     * @param  _quantity       The number of tokens to transfer
     */
    function withdrawTo(
        address _token,
        address _to,
        uint256 _quantity
    )
        external;

    /*
     * Increment quantity owned of a token for a given address. Can
     * only be called by authorized core contracts.
     *
     * @param  _token           The address of the ERC20 token
     * @param  _owner           The address of the token owner
     * @param  _quantity        The number of tokens to attribute to owner
     */
    function incrementTokenOwner(
        address _token,
        address _owner,
        uint256 _quantity
    )
        external;

    /*
     * Decrement quantity owned of a token for a given address. Can only
     * be called by authorized core contracts.
     *
     * @param  _token           The address of the ERC20 token
     * @param  _owner           The address of the token owner
     * @param  _quantity        The number of tokens to deattribute to owner
     */
    function decrementTokenOwner(
        address _token,
        address _owner,
        uint256 _quantity
    )
        external;

    /**
     * Transfers tokens associated with one account to another account in the vault
     *
     * @param  _token          Address of token being transferred
     * @param  _from           Address token being transferred from
     * @param  _to             Address token being transferred to
     * @param  _quantity       Amount of tokens being transferred
     */

    function transferBalance(
        address _token,
        address _from,
        address _to,
        uint256 _quantity
    )
        external;


    /*
     * Withdraws user's unassociated tokens to user account. Can only be
     * called by authorized core contracts.
     *
     * @param  _tokens          The addresses of the ERC20 tokens
     * @param  _owner           The address of the token owner
     * @param  _quantities      The numbers of tokens to attribute to owner
     */
    function batchWithdrawTo(
        address[] calldata _tokens,
        address _to,
        uint256[] calldata _quantities
    )
        external;

    /*
     * Increment quantites owned of a collection of tokens for a given address. Can
     * only be called by authorized core contracts.
     *
     * @param  _tokens          The addresses of the ERC20 tokens
     * @param  _owner           The address of the token owner
     * @param  _quantities      The numbers of tokens to attribute to owner
     */
    function batchIncrementTokenOwner(
        address[] calldata _tokens,
        address _owner,
        uint256[] calldata _quantities
    )
        external;

    /*
     * Decrements quantites owned of a collection of tokens for a given address. Can
     * only be called by authorized core contracts.
     *
     * @param  _tokens          The addresses of the ERC20 tokens
     * @param  _owner           The address of the token owner
     * @param  _quantities      The numbers of tokens to attribute to owner
     */
    function batchDecrementTokenOwner(
        address[] calldata _tokens,
        address _owner,
        uint256[] calldata _quantities
    )
        external;

   /**
     * Transfers tokens associated with one account to another account in the vault
     *
     * @param  _tokens           Addresses of tokens being transferred
     * @param  _from             Address tokens being transferred from
     * @param  _to               Address tokens being transferred to
     * @param  _quantities       Amounts of tokens being transferred
     */
    function batchTransferBalance(
        address[] calldata _tokens,
        address _from,
        address _to,
        uint256[] calldata _quantities
    )
        external;

    /*
     * Get balance of particular contract for owner.
     *
     * @param  _token    The address of the ERC20 token
     * @param  _owner    The address of the token owner
     */
    function getOwnerBalance(
        address _token,
        address _owner
    )
        external
        view
        returns (uint256);
}

// File: contracts/core/lib/CoreState.sol

/*
    Copyright 2018 Set Labs Inc.

    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.5.7;




/**
 * @title CoreState
 * @author Set Protocol
 *
 * The CoreState library maintains all state for the Core contract thus
 * allowing it to operate across multiple mixins.
 */
contract CoreState {

    /* ============ Structs ============ */

    struct State {
        // Protocol state of operation
        uint8 operationState;

        // Address of the TransferProxy contract
        address transferProxy;

        // Address of the Vault contract
        address vault;

        // Instance of transferProxy contract
        ITransferProxy transferProxyInstance;

        // Instance of Vault Contract
        IVault vaultInstance;

        // Mapping of exchange enumeration to address
        mapping(uint8 => address) exchangeIds;

        // Mapping of approved modules
        mapping(address => bool) validModules;

        // Mapping of tracked SetToken factories
        mapping(address => bool) validFactories;

        // Mapping of tracked rebalancing price libraries
        mapping(address => bool) validPriceLibraries;

        // Mapping of tracked SetTokens
        mapping(address => bool) validSets;

        // Mapping of tracked disabled SetTokens
        mapping(address => bool) disabledSets;

        // Array of tracked SetTokens
        address[] setTokens;

        // Array of tracked modules
        address[] modules;

        // Array of tracked factories
        address[] factories;

        // Array of tracked exchange wrappers
        address[] exchanges;

        // Array of tracked auction price libraries
        address[] priceLibraries;
    }

    /* ============ State Variables ============ */

    State public state;

    /* ============ Public Getters ============ */

    /**
     * Return uint8 representing the operational state of the protocol
     *
     * @return uint8           Uint8 representing the operational state of the protocol
     */
    function operationState()
        external
        view
        returns (uint8)
    {
        return state.operationState;
    }

    /**
     * Return address belonging to given exchangeId.
     *
     * @param  _exchangeId       ExchangeId number
     * @return address           Address belonging to given exchangeId
     */
    function exchangeIds(
        uint8 _exchangeId
    )
        external
        view
        returns (address)
    {
        return state.exchangeIds[_exchangeId];
    }

    /**
     * Return transferProxy address.
     *
     * @return address       transferProxy address
     */
    function transferProxy()
        external
        view
        returns (address)
    {
        return state.transferProxy;
    }

    /**
     * Return vault address
     *
     * @return address        vault address
     */
    function vault()
        external
        view
        returns (address)
    {
        return state.vault;
    }

    /**
     * Return boolean indicating if address is valid factory.
     *
     * @param  _factory       Factory address
     * @return bool           Boolean indicating if enabled factory
     */
    function validFactories(
        address _factory
    )
        external
        view
        returns (bool)
    {
        return state.validFactories[_factory];
    }

    /**
     * Return boolean indicating if address is valid module.
     *
     * @param  _module        Factory address
     * @return bool           Boolean indicating if enabled factory
     */
    function validModules(
        address _module
    )
        external
        view
        returns (bool)
    {
        return state.validModules[_module];
    }

    /**
     * Return boolean indicating if address is valid Set.
     *
     * @param  _set           Set address
     * @return bool           Boolean indicating if valid Set
     */
    function validSets(
        address _set
    )
        external
        view
        returns (bool)
    {
        return state.validSets[_set];
    }

    /**
     * Return boolean indicating if address is a disabled Set.
     *
     * @param  _set           Set address
     * @return bool           Boolean indicating if is a disabled Set
     */
    function disabledSets(
        address _set
    )
        external
        view
        returns (bool)
    {
        return state.disabledSets[_set];
    }

    /**
     * Return boolean indicating if address is a valid Rebalancing Price Library.
     *
     * @param  _priceLibrary    Price library address
     * @return bool             Boolean indicating if valid Price Library
     */
    function validPriceLibraries(
        address _priceLibrary
    )
        external
        view
        returns (bool)
    {
        return state.validPriceLibraries[_priceLibrary];
    }

    /**
     * Return array of all valid Set Tokens.
     *
     * @return address[]      Array of valid Set Tokens
     */
    function setTokens()
        external
        view
        returns (address[] memory)
    {
        return state.setTokens;
    }

    /**
     * Return array of all valid Modules.
     *
     * @return address[]      Array of valid modules
     */
    function modules()
        external
        view
        returns (address[] memory)
    {
        return state.modules;
    }

    /**
     * Return array of all valid factories.
     *
     * @return address[]      Array of valid factories
     */
    function factories()
        external
        view
        returns (address[] memory)
    {
        return state.factories;
    }

    /**
     * Return array of all valid exchange wrappers.
     *
     * @return address[]      Array of valid exchange wrappers
     */
    function exchanges()
        external
        view
        returns (address[] memory)
    {
        return state.exchanges;
    }

    /**
     * Return array of all valid price libraries.
     *
     * @return address[]      Array of valid price libraries
     */
    function priceLibraries()
        external
        view
        returns (address[] memory)
    {
        return state.priceLibraries;
    }
}

// File: contracts/core/extensions/CoreOperationState.sol

/*
    Copyright 2018 Set Labs Inc.

    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.5.7;




/**
 * @title CoreOperationState
 * @author Set Protocol
 *
 * The CoreOperationState contract contains methods to alter state of variables that track
 * Core dependency addresses.
 */
contract CoreOperationState is
    Ownable,
    CoreState
{

    /* ============ Enum ============ */

    /**
     * Operational:
     * All Accounting and Issuance related functions are available for usage during this stage
     *
     * Shut Down:
     * Only functions which allow users to redeem and withdraw funds are allowed during this stage
     */
    enum OperationState {
        Operational,
        ShutDown,
        InvalidState
    }

    /* ============ Events ============ */

    event OperationStateChanged(
        uint8 _prevState,
        uint8 _newState
    );

    /* ============ Modifiers ============ */

    modifier whenOperational() {
        require(
            state.operationState == uint8(OperationState.Operational),
            "WhenOperational"
        );
        _;
    }

    /* ============ External Functions ============ */

    /**
     * Updates the operation state of the protocol.
     * Can only be called by owner of Core.
     *
     * @param  _operationState   Uint8 representing the current protocol operation state
     */
    function setOperationState(
        uint8 _operationState
    )
        external
        onlyOwner
    {
        require(
            _operationState < uint8(OperationState.InvalidState) &&
            _operationState != state.operationState,
            "InvalidOperationState"
        );

        emit OperationStateChanged(
            state.operationState,
            _operationState
        );

        state.operationState = _operationState;
    }
}

// File: contracts/core/extensions/CoreAccounting.sol

/*
    Copyright 2018 Set Labs Inc.

    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.5.7;







/**
 * @title CoreAccounting
 * @author Set Protocol
 *
 * The CoreAccounting contract interfaces with the vault and transfer proxies for
 * storage of tokenized assets.
 */
contract CoreAccounting is
    CoreState,
    CoreOperationState,
    ReentrancyGuard
{
    // Use SafeMath library for all uint256 arithmetic
    using SafeMath for uint256;

    /* ============ External Functions ============ */

    /**
     * Deposit a quantity of tokens to the vault and attribute to sender.
     *
     * @param  _token           Address of the token
     * @param  _quantity        Amount of tokens to deposit
     */
    function deposit(
        address _token,
        uint256 _quantity
    )
        external
        nonReentrant
        whenOperational
    {
        // Don't deposit if quantity <= 0
        if (_quantity > 0) {
            // Call TransferProxy contract to transfer user tokens to Vault
            state.transferProxyInstance.transfer(
                _token,
                _quantity,
                msg.sender,
                state.vault
            );

            // Call Vault contract to attribute deposited tokens to user
            state.vaultInstance.incrementTokenOwner(
                _token,
                msg.sender,
                _quantity
            );
        }
    }

    /**
     * Withdraw a quantity of tokens from the vault and deattribute from sender.
     *
     * @param  _token           Address of the token
     * @param  _quantity        Amount of tokens to withdraw
     */
    function withdraw(
        address _token,
        uint256 _quantity
    )
        external
        nonReentrant
    {
        // Don't withdraw if quantity <= 0
        if (_quantity > 0) {
            // Call Vault contract to deattribute withdrawn tokens from user
            state.vaultInstance.decrementTokenOwner(
                _token,
                msg.sender,
                _quantity
            );

            // Call Vault contract to withdraw tokens from Vault to user
            state.vaultInstance.withdrawTo(
                _token,
                msg.sender,
                _quantity
            );
        }
    }

    /**
     * Deposit multiple tokens to the vault and attribute to sender.
     * Quantities should be in the order of the addresses of the tokens being deposited.
     *
     * @param  _tokens            Array of the addresses of the tokens
     * @param  _quantities        Array of the amounts of tokens to deposit
     */
    function batchDeposit(
        address[] calldata _tokens,
        uint256[] calldata _quantities
    )
        external
        nonReentrant
        whenOperational
    {
        // Call internal batch deposit function
        batchDepositInternal(
            msg.sender,
            msg.sender,
            _tokens,
            _quantities
        );
    }

    /**
     * Withdraw multiple tokens from the vault and deattribute from sender.
     * Quantities should be in the order of the addresses of the tokens being withdrawn.
     *
     * @param  _tokens            Array of the addresses of the tokens
     * @param  _quantities        Array of the amounts of tokens to withdraw
     */
    function batchWithdraw(
        address[] calldata _tokens,
        uint256[] calldata _quantities
    )
        external
        nonReentrant
    {
        // Call internal batch withdraw function
        batchWithdrawInternal(
            msg.sender,
            msg.sender,
            _tokens,
            _quantities
        );
    }

    /**
     * Transfer tokens associated with the sender's account in vault to another user's
     * account in vault.
     *
     * @param  _token           Address of token being transferred
     * @param  _to              Address of user receiving tokens
     * @param  _quantity        Amount of tokens being transferred
     */
    function internalTransfer(
        address _token,
        address _to,
        uint256 _quantity
    )
        external
        nonReentrant
        whenOperational
    {
        state.vaultInstance.transferBalance(
            _token,
            msg.sender,
            _to,
            _quantity
        );
    }

    /* ============ Internal Functions ============ */

    /**
     * Internal function that deposits multiple tokens to the vault.
     * Quantities should be in the order of the addresses of the tokens being deposited.
     *
     * @param  _from              Address to transfer tokens from
     * @param  _to                Address to credit for deposits
     * @param  _tokens            Array of the addresses of the tokens being deposited
     * @param  _quantities        Array of the amounts of tokens to deposit
     */
    function batchDepositInternal(
        address _from,
        address _to,
        address[] memory _tokens,
        uint256[] memory _quantities
    )
        internal
        whenOperational
    {
        // Confirm an empty _tokens or quantity array is not passed
        CommonValidationsLibrary.validateNonEmpty(_tokens);

        // Confirm there is one quantity for every token address
        CommonValidationsLibrary.validateEqualLength(_tokens, _quantities);

        state.transferProxyInstance.batchTransfer(
            _tokens,
            _quantities,
            _from,
            state.vault
        );

        state.vaultInstance.batchIncrementTokenOwner(
            _tokens,
            _to,
            _quantities
        );
    }

    /**
     * Internal function that withdraws multiple tokens from the vault.
     * Quantities should be in the order of the addresses of the tokens being withdrawn.
     *
     * @param  _from              Address to decredit for withdrawals
     * @param  _to                Address to transfer tokens to
     * @param  _tokens            Array of the addresses of the tokens being withdrawn
     * @param  _quantities        Array of the amounts of tokens to withdraw
     */
    function batchWithdrawInternal(
        address _from,
        address _to,
        address[] memory _tokens,
        uint256[] memory _quantities
    )
        internal
    {
        // Confirm an empty _tokens or quantity array is not passed
        CommonValidationsLibrary.validateNonEmpty(_tokens);

        // Confirm there is one quantity for every token address
        CommonValidationsLibrary.validateEqualLength(_tokens, _quantities);

        // Call Vault contract to deattribute withdrawn tokens from user
        state.vaultInstance.batchDecrementTokenOwner(
            _tokens,
            _from,
            _quantities
        );

        // Call Vault contract to withdraw tokens from Vault to user
        state.vaultInstance.batchWithdrawTo(
            _tokens,
            _to,
            _quantities
        );
    }
}

// File: contracts/lib/AddressArrayUtils.sol

// Pulled in from Cryptofin Solidity package in order to control Solidity compiler version
// https://github.com/cryptofinlabs/cryptofin-solidity/blob/master/contracts/array-utils/AddressArrayUtils.sol

pragma solidity 0.5.7;


library AddressArrayUtils {

    /**
     * Finds the index of the first occurrence of the given element.
     * @param A The input array to search
     * @param a The value to find
     * @return Returns (index and isIn) for the first occurrence starting from index 0
     */
    function indexOf(address[] memory A, address a) internal pure returns (uint256, bool) {
        uint256 length = A.length;
        for (uint256 i = 0; i < length; i++) {
            if (A[i] == a) {
                return (i, true);
            }
        }
        return (0, false);
    }

    /**
    * Returns true if the value is present in the list. Uses indexOf internally.
    * @param A The input array to search
    * @param a The value to find
    * @return Returns isIn for the first occurrence starting from index 0
    */
    function contains(address[] memory A, address a) internal pure returns (bool) {
        bool isIn;
        (, isIn) = indexOf(A, a);
        return isIn;
    }

    /// @return Returns index and isIn for the first occurrence starting from
    /// end
    function indexOfFromEnd(address[] memory A, address a) internal pure returns (uint256, bool) {
        uint256 length = A.length;
        for (uint256 i = length; i > 0; i--) {
            if (A[i - 1] == a) {
                return (i, true);
            }
        }
        return (0, false);
    }

    /**
     * Returns the combination of the two arrays
     * @param A The first array
     * @param B The second array
     * @return Returns A extended by B
     */
    function extend(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        uint256 aLength = A.length;
        uint256 bLength = B.length;
        address[] memory newAddresses = new address[](aLength + bLength);
        for (uint256 i = 0; i < aLength; i++) {
            newAddresses[i] = A[i];
        }
        for (uint256 j = 0; j < bLength; j++) {
            newAddresses[aLength + j] = B[j];
        }
        return newAddresses;
    }

    /**
     * Returns the array with a appended to A.
     * @param A The first array
     * @param a The value to append
     * @return Returns A appended by a
     */
    function append(address[] memory A, address a) internal pure returns (address[] memory) {
        address[] memory newAddresses = new address[](A.length + 1);
        for (uint256 i = 0; i < A.length; i++) {
            newAddresses[i] = A[i];
        }
        newAddresses[A.length] = a;
        return newAddresses;
    }

    /**
     * Returns the combination of two storage arrays.
     * @param A The first array
     * @param B The second array
     * @return Returns A appended by a
     */
    function sExtend(address[] storage A, address[] storage B) internal {
        uint256 length = B.length;
        for (uint256 i = 0; i < length; i++) {
            A.push(B[i]);
        }
    }

    /**
     * Returns the intersection of two arrays. Arrays are treated as collections, so duplicates are kept.
     * @param A The first array
     * @param B The second array
     * @return The intersection of the two arrays
     */
    function intersect(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        uint256 length = A.length;
        bool[] memory includeMap = new bool[](length);
        uint256 newLength = 0;
        for (uint256 i = 0; i < length; i++) {
            if (contains(B, A[i])) {
                includeMap[i] = true;
                newLength++;
            }
        }
        address[] memory newAddresses = new address[](newLength);
        uint256 j = 0;
        for (uint256 k = 0; k < length; k++) {
            if (includeMap[k]) {
                newAddresses[j] = A[k];
                j++;
            }
        }
        return newAddresses;
    }

    /**
     * Returns the union of the two arrays. Order is not guaranteed.
     * @param A The first array
     * @param B The second array
     * @return The union of the two arrays
     */
    function union(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        address[] memory leftDifference = difference(A, B);
        address[] memory rightDifference = difference(B, A);
        address[] memory intersection = intersect(A, B);
        return extend(leftDifference, extend(intersection, rightDifference));
    }

    /**
     * Alternate implementation
     * Assumes there are no duplicates
     */
    function unionB(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        bool[] memory includeMap = new bool[](A.length + B.length);
        uint256 count = 0;
        for (uint256 i = 0; i < A.length; i++) {
            includeMap[i] = true;
            count++;
        }
        for (uint256 j = 0; j < B.length; j++) {
            if (!contains(A, B[j])) {
                includeMap[A.length + j] = true;
                count++;
            }
        }
        address[] memory newAddresses = new address[](count);
        uint256 k = 0;
        for (uint256 m = 0; m < A.length; m++) {
            if (includeMap[m]) {
                newAddresses[k] = A[m];
                k++;
            }
        }
        for (uint256 n = 0; n < B.length; n++) {
            if (includeMap[A.length + n]) {
                newAddresses[k] = B[n];
                k++;
            }
        }
        return newAddresses;
    }

    /**
     * Computes the difference of two arrays. Assumes there are no duplicates.
     * @param A The first array
     * @param B The second array
     * @return The difference of the two arrays
     */
    function difference(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        uint256 length = A.length;
        bool[] memory includeMap = new bool[](length);
        uint256 count = 0;
        // First count the new length because can't push for in-memory arrays
        for (uint256 i = 0; i < length; i++) {
            address e = A[i];
            if (!contains(B, e)) {
                includeMap[i] = true;
                count++;
            }
        }
        address[] memory newAddresses = new address[](count);
        uint256 j = 0;
        for (uint256 k = 0; k < length; k++) {
            if (includeMap[k]) {
                newAddresses[j] = A[k];
                j++;
            }
        }
        return newAddresses;
    }

    /**
    * @dev Reverses storage array in place
    */
    function sReverse(address[] storage A) internal {
        address t;
        uint256 length = A.length;
        for (uint256 i = 0; i < length / 2; i++) {
            t = A[i];
            A[i] = A[A.length - i - 1];
            A[A.length - i - 1] = t;
        }
    }

    /**
    * Removes specified index from array
    * Resulting ordering is not guaranteed
    * @return Returns the new array and the removed entry
    */
    function pop(address[] memory A, uint256 index)
        internal
        pure
        returns (address[] memory, address)
    {
        uint256 length = A.length;
        address[] memory newAddresses = new address[](length - 1);
        for (uint256 i = 0; i < index; i++) {
            newAddresses[i] = A[i];
        }
        for (uint256 j = index + 1; j < length; j++) {
            newAddresses[j - 1] = A[j];
        }
        return (newAddresses, A[index]);
    }

    /**
     * @return Returns the new array
     */
    function remove(address[] memory A, address a)
        internal
        pure
        returns (address[] memory)
    {
        (uint256 index, bool isIn) = indexOf(A, a);
        if (!isIn) {
            revert();
        } else {
            (address[] memory _A,) = pop(A, index);
            return _A;
        }
    }

    function sPop(address[] storage A, uint256 index) internal returns (address) {
        uint256 length = A.length;
        if (index >= length) {
            revert("Error: index out of bounds");
        }
        address entry = A[index];
        for (uint256 i = index; i < length - 1; i++) {
            A[i] = A[i + 1];
        }
        A.length--;
        return entry;
    }

    /**
    * Deletes address at index and fills the spot with the last address.
    * Order is not preserved.
    * @return Returns the removed entry
    */
    function sPopCheap(address[] storage A, uint256 index) internal returns (address) {
        uint256 length = A.length;
        if (index >= length) {
            revert("Error: index out of bounds");
        }
        address entry = A[index];
        if (index != length - 1) {
            A[index] = A[length - 1];
            delete A[length - 1];
        }
        A.length--;
        return entry;
    }

    /**
     * Deletes address at index. Works by swapping it with the last address, then deleting.
     * Order is not preserved
     * @param A Storage array to remove from
     */
    function sRemoveCheap(address[] storage A, address a) internal {
        (uint256 index, bool isIn) = indexOf(A, a);
        if (!isIn) {
            revert("Error: entry not found");
        } else {
            sPopCheap(A, index);
            return;
        }
    }

    /**
     * Returns whether or not there's a duplicate. Runs in O(n^2).
     * @param A Array to search
     * @return Returns true if duplicate, false otherwise
     */
    function hasDuplicate(address[] memory A) internal pure returns (bool) {
        if (A.length == 0) {
            return false;
        }
        for (uint256 i = 0; i < A.length - 1; i++) {
            for (uint256 j = i + 1; j < A.length; j++) {
                if (A[i] == A[j]) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Returns whether the two arrays are equal.
     * @param A The first array
     * @param B The second array
     * @return True is the arrays are equal, false if not.
     */
    function isEqual(address[] memory A, address[] memory B) internal pure returns (bool) {
        if (A.length != B.length) {
            return false;
        }
        for (uint256 i = 0; i < A.length; i++) {
            if (A[i] != B[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns the elements indexed at indexArray.
     * @param A The array to index
     * @param indexArray The array to use to index
     * @return Returns array containing elements indexed at indexArray
     */
    function argGet(address[] memory A, uint256[] memory indexArray)
        internal
        pure
        returns (address[] memory)
    {
        address[] memory array = new address[](indexArray.length);
        for (uint256 i = 0; i < indexArray.length; i++) {
            array[i] = A[indexArray[i]];
        }
        return array;
    }

}

// File: contracts/lib/TimeLockUpgrade.sol

/*
    Copyright 2018 Set Labs Inc.

    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.5.7;




/**
 * @title TimeLockUpgrade
 * @author Set Protocol
 *
 * The TimeLockUpgrade contract contains a modifier for handling minimum time period updates
 */
contract TimeLockUpgrade is
    Ownable
{
    using SafeMath for uint256;

    /* ============ State Variables ============ */

    // Timelock Upgrade Period in seconds
    uint256 public timeLockPeriod;

    // Mapping of upgradable units and initialized timelock
    mapping(bytes32 => uint256) public timeLockedUpgrades;

    /* ============ Events ============ */

    event UpgradeRegistered(
        bytes32 _upgradeHash,
        uint256 _timestamp
    );

    /* ============ Modifiers ============ */

    modifier timeLockUpgrade() {
        // If the time lock period is 0, then allow non-timebound upgrades.
        // This is useful for initialization of the protocol and for testing.
        if (timeLockPeriod == 0) {
            _;

            return;
        }

        // The upgrade hash is defined by the hash of the transaction call data,
        // which uniquely identifies the function as well as the passed in arguments.
        bytes32 upgradeHash = keccak256(
            abi.encodePacked(
                msg.data
            )
        );

        uint256 registrationTime = timeLockedUpgrades[upgradeHash];

        // If the upgrade hasn't been registered, register with the current time.
        if (registrationTime == 0) {
            timeLockedUpgrades[upgradeHash] = block.timestamp;

            emit UpgradeRegistered(
                upgradeHash,
                block.timestamp
            );

            return;
        }

        require(
            block.timestamp >= registrationTime.add(timeLockPeriod),
            "TimeLockUpgrade: Time lock period must have elapsed."
        );

        // Reset the timestamp to 0
        timeLockedUpgrades[upgradeHash] = 0;

        // Run the rest of the upgrades
        _;
    }

    /* ============ Function ============ */

    /**
     * Change timeLockPeriod period. Generally called after initially settings have been set up.
     *
     * @param  _timeLockPeriod   Time in seconds that upgrades need to be evaluated before execution
     */
    function setTimeLockPeriod(
        uint256 _timeLockPeriod
    )
        external
        onlyOwner
    {
        // Only allow setting of the timeLockPeriod if the period is greater than the existing
        require(
            _timeLockPeriod > timeLockPeriod,
            "TimeLockUpgrade: New period must be greater than existing"
        );

        timeLockPeriod = _timeLockPeriod;
    }
}

// File: contracts/core/extensions/CoreAdmin.sol

/*
    Copyright 2018 Set Labs Inc.

    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.5.7;






/**
 * @title CoreAdmin
 * @author Set Protocol
 *
 * The CoreAdmin contract contains methods to alter state of variables that track
 * Core dependency addresses.
 */
contract CoreAdmin is
    Ownable,
    CoreState,
    TimeLockUpgrade
{
    using AddressArrayUtils for address[];

    /* ============ Events ============ */

    event FactoryAdded(
        address _factory
    );

    event FactoryRemoved(
        address _factory
    );

    event ExchangeAdded(
        uint8 _exchangeId,
        address _exchange
    );

    event ExchangeRemoved(
        uint8 _exchangeId
    );

    event ModuleAdded(
        address _module
    );

    event ModuleRemoved(
        address _module
    );

    event SetDisabled(
        address _set
    );

    event SetReenabled(
        address _set
    );

    event PriceLibraryAdded(
        address _priceLibrary
    );

    event PriceLibraryRemoved(
        address _priceLibrary
    );

    /* ============ External Functions ============ */

    /**
     * Add a factory from the mapping of tracked factories.
     * Can only be called by owner of Core.
     *
     * @param  _factory   Address of the factory conforming to ISetFactory
     */
    function addFactory(
        address _factory
    )
        external
        onlyOwner
        timeLockUpgrade
    {
        require(
            !state.validFactories[_factory]
        );

        state.validFactories[_factory] = true;

        state.factories = state.factories.append(_factory);

        emit FactoryAdded(
            _factory
        );
    }

    /**
     * Remove a factory from the mapping of tracked factories.
     * Can only be called by owner of Core.
     *
     * @param  _factory   Address of the factory conforming to ISetFactory
     */
    function removeFactory(
        address _factory
    )
        external
        onlyOwner
    {
        require(
            state.validFactories[_factory]
        );

        state.factories = state.factories.remove(_factory);

        state.validFactories[_factory] = false;

        emit FactoryRemoved(
            _factory
        );
    }

    /**
     * Add an exchange address with the mapping of tracked exchanges.
     * Can only be called by owner of Core.
     *
     * @param _exchangeId   Enumeration of exchange within the mapping...

// [truncated — 105298 bytes total]

Read Contract

disabledSets 0xd913d4e1 → bool
exchangeIds 0x56fe2784 → address
exchanges 0x21a8c177 → address[]
factories 0xfe5b38e4 → address[]
isOwner 0x8f32d59b → bool
modules 0xf7e80e98 → address[]
operationState 0x72bedcee → uint8
owner 0x8da5cb5b → address
priceLibraries 0xd0312561 → address[]
setTokens 0x559ed339 → address[]
state 0xc19d93fb → uint8, address, address, address, address
timeLockPeriod 0x78446bc1 → uint256
timeLockedUpgrades 0x1766486d → uint256
transferProxy 0x6e667db3 → address
validFactories 0x0e4355d4 → bool
validModules 0x5e633498 → bool
validPriceLibraries 0xa2c9eb6d → bool
validSets 0xfef3ee73 → bool
vault 0xfbfa77cf → address

Write Contract 39 functions

These functions modify contract state and require a wallet transaction to execute.

addExchange 0x50528ec5
uint8 _exchangeId
address _exchange
addFactory 0x29ce1ec5
address _factory
addModule 0x1ed86f19
address _module
addPriceLibrary 0xe2523632
address _priceLibrary
batchDecrementTokenOwnerModule 0xca1ce8ce
address[] _tokens
address _owner
uint256[] _quantities
batchDeposit 0x30a90736
address[] _tokens
uint256[] _quantities
batchDepositModule 0xcaaa3ada
address _from
address _to
address[] _tokens
uint256[] _quantities
batchIncrementTokenOwnerModule 0x34650cd7
address[] _tokens
address _owner
uint256[] _quantities
batchTransferBalanceModule 0x55d2d9cd
address[] _tokens
address _from
address _to
uint256[] _quantities
batchTransferModule 0x52a5ce53
address[] _tokens
uint256[] _quantities
address _from
address _to
batchWithdraw 0xe131243e
address[] _tokens
uint256[] _quantities
batchWithdrawModule 0xfe93620e
address _from
address _to
address[] _tokens
uint256[] _quantities
createSet 0x5c217114
address _factory
address[] _components
uint256[] _units
uint256 _naturalUnit
bytes32 _name
bytes32 _symbol
bytes _callData
returns: address
deposit 0x47e7ef24
address _token
uint256 _quantity
depositModule 0xde30f6ee
address _from
address _to
address _token
uint256 _quantity
disableSet 0x77274ff0
address _set
internalTransfer 0x59e026f7
address _token
address _to
uint256 _quantity
issue 0x867904b4
address _set
uint256 _quantity
issueInVault 0xa57de4cf
address _set
uint256 _quantity
issueInVaultModule 0x7add12a6
address _recipient
address _set
uint256 _quantity
issueModule 0x7c68561f
address _componentOwner
address _setRecipient
address _set
uint256 _quantity
issueTo 0x73088bf7
address _recipient
address _set
uint256 _quantity
redeem 0x1e9a6950
address _set
uint256 _quantity
redeemAndWithdrawTo 0x1c2a0e40
address _set
address _to
uint256 _quantity
uint256 _toExclude
redeemInVault 0xa782132c
address _set
uint256 _quantity
redeemModule 0x5990ca08
address _burnAddress
address _incrementAddress
address _set
uint256 _quantity
redeemTo 0xea466061
address _recipient
address _set
uint256 _quantity
reenableSet 0x186babb2
address _set
removeExchange 0x0ed09d50
uint8 _exchangeId
address _exchange
removeFactory 0x4b37c73f
address _factory
removeModule 0xa0632461
address _module
removePriceLibrary 0x3795d945
address _priceLibrary
renounceOwnership 0x715018a6
No parameters
setOperationState 0x539f70d8
uint8 _operationState
setTimeLockPeriod 0x9303b16f
uint256 _timeLockPeriod
transferModule 0xfd496ebf
address _token
uint256 _quantity
address _from
address _to
transferOwnership 0xf2fde38b
address newOwner
withdraw 0xf3fef3a3
address _token
uint256 _quantity
withdrawModule 0x0e1fd334
address _from
address _to
address _token
uint256 _quantity

Recent Transactions

No transactions found for this address