Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xbf686dA68323d0425f2B0D7e33d3fA11B1239132
Balance 0 ETH
Nonce 1
Code Size 18447 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

18447 bytes
0x608060405234801561001057600080fd5b506004361061023c5760003560e01c8063959b8c3f1161013b578063d95b6371116100b8578063e90dd9e21161007c578063e90dd9e214610f2d578063fad8b32a14610f4b578063fbd7d75214610f8f578063fc673c4f14611032578063fe9d93031461112a5761023c565b8063d95b637114610d61578063db07844914610ddd578063dd62ed3e14610e15578063e186719e14610e8d578063e47fca4e14610ee95761023c565b8063a9f83f82116100ff578063a9f83f8214610bbb578063b2beab0314610c29578063b89f378a14610c85578063c6eb68fa14610ccf578063d84a25b714610d1f5761023c565b8063959b8c3f1461099b57806395d89b41146109df5780639bd9bbc614610a62578063a04b1e9014610b05578063a9059cbb14610b555761023c565b80633c858577116101c95780636f54ed751161018d5780636f54ed751461082157806370a08231146108635780637de891d6146108bb5780638da5cb5b1461090b5780638dfdd8a1146109555761023c565b80633c8585771461061757806340c10f191461064f578063556f0dc71461069d57806362ad1b83146106bb5780636eac7739146107d35761023c565b80631171ffcf116102105780631171ffcf146104c157806313af40351461050b57806318160ddd1461054f57806323b872dd1461056d578063313ce567146105f35761023c565b806223de291461024157806306e485381461037957806306fdde03146103d8578063095ea7b31461045b575b600080fd5b610377600480360360c081101561025757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156102de57600080fd5b8201836020820111156102f057600080fd5b8035906020019184600183028401116401000000008311171561031257600080fd5b90919293919293908035906020019064010000000081111561033357600080fd5b82018360208201111561034557600080fd5b8035906020019184600183028401116401000000008311171561036757600080fd5b90919293919293905050506111ad565b005b610381611793565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156103c45780820151818401526020810190506103a9565b505050509050019250505060405180910390f35b6103e0611824565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610420578082015181840152602081019050610405565b50505050905090810190601f16801561044d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104a76004803603604081101561047157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506118c6565b604051808215151515815260200191505060405180910390f35b6104c9611976565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61054d6004803603602081101561052157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061199a565b005b610557611bc0565b6040518082815260200191505060405180910390f35b6105d96004803603606081101561058357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611bcd565b604051808215151515815260200191505060405180910390f35b6105fb611cb2565b604051808260ff1660ff16815260200191505060405180910390f35b61064d6004803603604081101561062d57600080fd5b810190808035906020019092919080359060200190929190505050611cbb565b005b61069b6004803603604081101561066557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611dcb565b005b6106a5611f35565b6040518082815260200191505060405180910390f35b6107d1600480360360a08110156106d157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561073857600080fd5b82018360208201111561074a57600080fd5b8035906020019184600183028401116401000000008311171561076c57600080fd5b90919293919293908035906020019064010000000081111561078d57600080fd5b82018360208201111561079f57600080fd5b803590602001918460018302840111640100000000831117156107c157600080fd5b9091929391929390505050611f3e565b005b61081f600480360360408110156107e957600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061205d565b005b61084d6004803603602081101561083757600080fd5b81019080803590602001909291905050506122d8565b6040518082815260200191505060405180910390f35b6108a56004803603602081101561087957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122f0565b6040518082815260200191505060405180910390f35b610909600480360360408110156108d157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080351515906020019092919050505061233c565b005b610913612551565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109816004803603602081101561096b57600080fd5b8101908080359060200190929190505050612577565b604051808215151515815260200191505060405180910390f35b6109dd600480360360208110156109b157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612597565b005b6109e7612636565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a27578082015181840152602081019050610a0c565b50505050905090810190601f168015610a545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610b0360048036036060811015610a7857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610abf57600080fd5b820183602082011115610ad157600080fd5b80359060200191846001830284011164010000000083111715610af357600080fd5b90919293919293905050506126d8565b005b610b5360048036036040811015610b1b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612741565b005b610ba160048036036040811015610b6b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061291d565b604051808215151515815260200191505060405180910390f35b610be760048036036020811015610bd157600080fd5b8101908080359060200190929190505050612957565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c6b60048036036020811015610c3f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061298a565b604051808215151515815260200191505060405180910390f35b610c8d6129aa565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d1d60048036036040811015610ce557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506129d0565b005b610d4b60048036036020811015610d3557600080fd5b8101908080359060200190929190505050612be5565b6040518082815260200191505060405180910390f35b610dc360048036036040811015610d7757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612bfd565b604051808215151515815260200191505060405180910390f35b610e1360048036036040811015610df357600080fd5b810190808035906020019092919080359060200190929190505050612d59565b005b610e7760048036036040811015610e2b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f8b565b6040518082815260200191505060405180910390f35b610ecf60048036036020811015610ea357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613014565b604051808215151515815260200191505060405180910390f35b610f2b60048036036020811015610eff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613034565b005b610f35613223565b6040518082815260200191505060405180910390f35b610f8d60048036036020811015610f6157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061322f565b005b61103060048036036060811015610fa557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610fec57600080fd5b820183602082011115610ffe57600080fd5b8035906020019184600183028401116401000000008311171561102057600080fd5b90919293919293905050506132ce565b005b6111286004803603608081101561104857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108f57600080fd5b8201836020820111156110a157600080fd5b803590602001918460018302840111640100000000831117156110c357600080fd5b9091929391929390803590602001906401000000008111156110e457600080fd5b8201836020820111156110f657600080fd5b8035906020019184600183028401116401000000008311171561111857600080fd5b909192939192939050505061352d565b005b6111ab6004803603604081101561114057600080fd5b81019080803590602001909291908035906020019064010000000081111561116757600080fd5b82018360208201111561117957600080fd5b8035906020019184600183028401116401000000008311171561119b57600080fd5b9091929391929390505050613648565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461124e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6f6e6c794f776e546f6b656e730000000000000000000000000000000000000081525060200191505060405180910390fd5b6000806000606060006060898960c081101561126957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156112d057600080fd5b8201836020820111156112e257600080fd5b8035906020019184600183028401116401000000008311171561130457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291908035906020019064010000000081111561137157600080fd5b82018360208201111561138357600080fd5b803590602001918460018302840111640100000000831117156113a557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505095509550955095509550955061140c8686868686866136ad565b60008b146114c8573073ffffffffffffffffffffffffffffffffffffffff16639bd9bbc6878d6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001806020018281038252600081526020016020019350505050600060405180830381600087803b1580156114af57600080fd5b505af11580156114c3573d6000803e3d6000fd5b505050505b3073ffffffffffffffffffffffffffffffffffffffff166362ad1b83878787878f8f6040518763ffffffff1660e01b8152600401808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018060200180602001838103835286818151815260200191508051906020019080838360005b838110156115a757808201518184015260208101905061158c565b50505050905090810190601f1680156115d45780820380516001836020036101000a031916815260200191505b508381038252858582818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050600060405180830381600087803b15801561162457600080fd5b505af1158015611638573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f97823a4edabb1c2f3fb4ee63160c204ef488f4d2282a0bdd4290cdde86c708ec86868686604051808581526020018060200184815260200180602001838103835286818151815260200191508051906020019080838360005b838110156116df5780820151818401526020810190506116c4565b50505050905090810190601f16801561170c5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561174557808201518184015260208101905061172a565b50505050905090810190601f1680156117725780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a35050505050505050505050505050565b6060600260040180548060200260200160405190810160405280929190818152602001828054801561181a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116117d0575b5050505050905090565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118bc5780601f10611891576101008083540402835291602001916118bc565b820191906000526020600020905b81548152906001019060200180831161189f57829003601f168201915b5050505050905090565b60007360ca4ec4412a3b319f4bd6366bb836395336b397638bde1d78600285856040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060006040518083038186803b15801561195457600080fd5b505af4158015611968573d6000803e3d6000fd5b505050506001905092915050565b7f0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb81565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a5d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206d757374206265206f776e657200000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4f776e65722063616e6e6f74206265207a65726f20616464726573730000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fdb6d05f3295cede580affa301a1eb5297528f3b3f6a56b075887ce6f61c45f2160405160405180910390a380600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600260000154905090565b60007360ca4ec4412a3b319f4bd6366bb836395336b397632e6a560960028686866040518563ffffffff1660e01b8152600401808581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060006040518083038186803b158015611c8f57600080fd5b505af4158015611ca3573d6000803e3d6000fd5b50505050600190509392505050565b60006012905090565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f6f6e6c795553445261746553657474657200000000000000000000000000000081525060200191505060405180910390fd5b611d888282613967565b7fcc375191748c1570d8cc8f49eb8a77b2d411830d2c609dbc4ea2b29dc56f68dc8282604051808381526020018281526020019250505060405180910390a15050565b600260060160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f6f6e6c794d696e7465720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b7360ca4ec4412a3b319f4bd6366bb836395336b397636eeb9e0f600284846040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060006040518083038186803b158015611f1957600080fd5b505af4158015611f2d573d6000803e3d6000fd5b505050505050565b60006001905090565b86611f493382612bfd565b611fbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4e6f7420616e206f70657261746f72000000000000000000000000000000000081525060200191505060405180910390fd5b6120533389898989898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505088888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506001613a7f565b5050505050505050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612120576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206d757374206265206f776e657200000000000000000000000081525060200191505060405180910390fd5b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156121c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f416464726573732063616e6e6f74206265206e756c6c0000000000000000000081525060200191505060405180910390fd5b6000801b83141561223d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4d697373696e67206b657920686173680000000000000000000000000000000081525060200191505060405180910390fd5b81600e600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff16837f0ada7f316e371f763b084899958ab4f7c3eac45ded64a568087925f39d47bf2360405160405180910390a3505050565b600b81600281106122e557fe5b016000915090505481565b6000600260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146123ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206d757374206265206f776e657200000000000000000000000081525060200191505060405180910390fd5b81600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156124a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f416464726573732063616e6e6f74206265206e756c6c0000000000000000000081525060200191505060405180910390fd5b81601060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff167fdfe7f55d642b44ed109bb2549db5e1cbaa5e7997a6cb1c15bc0d4a282d00822b83604051808215151515815260200191505060405180910390a2505050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a6020528060005260406000206000915054906101000a900460ff1681565b7360ca4ec4412a3b319f4bd6366bb836395336b39763528aa17e6002836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b15801561261b57600080fd5b505af415801561262f573d6000803e3d6000fd5b5050505050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156126ce5780601f106126a3576101008083540402835291602001916126ce565b820191906000526020600020905b8154815290600101906020018083116126b157829003601f168201915b5050505050905090565b61273b3333868686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050604051806020016040528060008152506001613a7f565b50505050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612804576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206d757374206265206f776e657200000000000000000000000081525060200191505060405180910390fd5b81600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156128a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f416464726573732063616e6e6f74206265206e756c6c0000000000000000000081525060200191505060405180910390fd5b81156128bc576128b783613bb1565b6128c6565b6128c583613cb3565b5b8273ffffffffffffffffffffffffffffffffffffffff167ff2bddba4dbca95e342065cf53fe3ea5804c27f6d053eea0ef7c8d913a4081acb83604051808215151515815260200191505060405180910390a2505050565b600061294d3333858560405180602001604052806000815250604051806020016040528060008152506000613a7f565b6001905092915050565b600e6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600f6020528060005260406000206000915054906101000a900460ff1681565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612a93576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206d757374206265206f776e657200000000000000000000000081525060200191505060405180910390fd5b81600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612b37576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f416464726573732063616e6e6f74206265206e756c6c0000000000000000000081525060200191505060405180910390fd5b81600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff167f363e463e09657c2fceb1bb6e7e00014a6c2e513c9e5bc4e5e3a2e87a51b8fa3f83604051808215151515815260200191505060405180910390a2505050565b60118160028110612bf257fe5b016000915090505481565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161480612cc25750600260030160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b80612d5157503073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16148015612d505750600260050160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b5b905092915050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e1c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206d757374206265206f776e657200000000000000000000000081525060200191505060405180910390fd5b6000811415612e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206275726e20726174696f3a20646976206279207a65726f0081525060200191505060405180910390fd5b81811015612f09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206275726e20726174696f3a2061626f76652031303025000081525060200191505060405180910390fd5b6040518060400160405280838152602001828152506011906002612f2e92919061470f565b507f1475106783249a413aa8777c98a14e278e91f0f5eef337bea65868655f8a721d6011604051808260028015612f7a576020028201915b815481526020019060010190808311612f66575b505091505060405180910390a15050565b60006002800160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60106020528060005260406000206000915054906101000a900460ff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146130f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f53656e646572206d757374206265206f776e657200000000000000000000000081525060200191505060405180910390fd5b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561319b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f416464726573732063616e6e6f74206265206e756c6c0000000000000000000081525060200191505060405180910390fd5b81600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff167f5ff20ba4bf41ff0e6c7e644533c6174e64a3126129f9016279fcdf8b5575efec60405160405180910390a25050565b60028060000154905081565b7360ca4ec4412a3b319f4bd6366bb836395336b39763a77f752c6002836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b1580156132b357600080fd5b505af41580156132c7573d6000803e3d6000fd5b5050505050565b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661338d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f6f6e6c794c69667465720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600e600060405160200180807f46545363616c696e674d616e6167657200000000000000000000000000000000815250601001905060405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503073ffffffffffffffffffffffffffffffffffffffff166362ad1b8386838787876040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200180602001806020018381038352858582818152602001925080828437600081840152601f19601f820116905080830192505050838103825260008152602001602001975050505050505050600060405180830381600087803b15801561350e57600080fd5b505af1158015613522573d6000803e3d6000fd5b505050505050505050565b856135383382612bfd565b6135aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4e6f7420616e206f70657261746f72000000000000000000000000000000000081525060200191505060405180910390fd5b61363f33888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613db5565b50505050505050565b6136a833338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060405180602001604052806000815250613db5565b505050565b600a60008280519060200120815260200190815260200160002060009054906101000a900460ff1615613748576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f50726f78792070726f6f66206e6f7420756e697175650000000000000000000081525060200191505060405180910390fd5b6001600a60008380519060200120815260200190815260200160002060006101000a81548160ff0219169083151502179055506000308787878787604051602001808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140184815260200183805190602001908083835b6020831061385e578051825260208201915060208101905060208303925061383b565b6001836020036101000a038019825116818451168082178552505050505050905001828152602001965050505050505060405160208183030381529060405280519060200120905060006138ba6138b483613f6e565b84613fc6565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461395d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f426164207369676e65720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050505050565b60008214156139de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f6e756d546f6b656e732063616e6e6f74206265207a65726f000000000000000081525060200191505060405180910390fd5b6000811415613a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f6e756d5553442063616e6e6f74206265207a65726f000000000000000000000081525060200191505060405180910390fd5b604051806040016040528083815260200182815250600b906002613a7a92919061470f565b505050565b6000849050601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015613b285750601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b15613b98576000613b726011600160028110613b4057fe5b0154613b646011600060028110613b5357fe5b01548961427490919063ffffffff16565b6142fa90919063ffffffff16565b9050613b818989838888613db5565b613b94818361434490919063ffffffff16565b9150505b613ba78888888488888861438e565b5050505050505050565b7360ca4ec4412a3b319f4bd6366bb836395336b397638c96a55d6002836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b158015613c3557600080fd5b505af4158015613c49573d6000803e3d6000fd5b505050507fa1d81f39379cbd3fc0b41e0f22ac869eee88b0a7f221bf424e2db0eadb900b7b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b7360ca4ec4412a3b319f4bd6366bb836395336b3976353a7daf46002836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b158015613d3757600080fd5b505af4158015613d4b573d6000803e3d6000fd5b505050507f8e768d7a5530d1f68e76ded405597f5ab4e340da31733f8704353e0b62b911f881604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b7360ca4ec4412a3b319f4bd6366bb836395336b3976324394467600287878787876040518763ffffffff1660e01b8152600401808781526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015613e99578082015181840152602081019050613e7e565b50505050905090810190601f168015613ec65780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015613eff578082015181840152602081019050613ee4565b50505050905090810190601f168015613f2c5780820380516001836020036101000a031916815260200191505b509850505050505050505060006040518083038186803b158015613f4f57600080fd5b505af4158015613f63573d6000803e3d6000fd5b505050505050505050565b60008160405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c01828152602001915050604051602081830303815290604052805190602001209050919050565b6000604182511461403f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45434453413a20696e76616c6964207369676e6174757265206c656e6774680081525060200191505060405180910390fd5b60008060006020850151925060408501519150606085015160001a90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c11156140d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806147756022913960400191505060405180910390fd5b601b8160ff1610156140eb57601b810190505b601b8160ff16141580156141035750601c8160ff1614155b15614159576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806147976022913960400191505060405180910390fd5b600060018783868660405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156141b8573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415614267576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f45434453413a20696e76616c6964207369676e6174757265000000000000000081525060200191505060405180910390fd5b8094505050505092915050565b60008083141561428757600090506142f4565b600082840290508284828161429857fe5b04146142ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806147b96021913960400191505060405180910390fd5b809150505b92915050565b600061433c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614589565b905092915050565b600061438683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061464f565b905092915050565b7360ca4ec4412a3b319f4bd6366bb836395336b39763b750dc466002898989898989896040518963ffffffff1660e01b8152600401808981526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001806020018060200184151515158152602001838103835286818151815260200191508051906020019080838360005b838110156144b0578082015181840152602081019050614495565b50505050905090810190601f1680156144dd5780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b838110156145165780820151818401526020810190506144fb565b50505050905090810190601f1680156145435780820380516001836020036101000a031916815260200191505b509a505050505050505050505060006040518083038186803b15801561456857600080fd5b505af415801561457c573d6000803e3d6000fd5b5050505050505050505050565b60008083118290614635576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156145fa5780820151818401526020810190506145df565b50505050905090810190601f1680156146275780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161464157fe5b049050809150509392505050565b60008383111582906146fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156146c15780820151818401526020810190506146a6565b50505050905090810190601f1680156146ee5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b826002810192821561473e579160200282015b8281111561473d578251825591602001919060010190614722565b5b50905061474b919061474f565b5090565b61477191905b8082111561476d576000816000905550600101614755565b5090565b9056fe45434453413a20696e76616c6964207369676e6174757265202773272076616c756545434453413a20696e76616c6964207369676e6174757265202776272076616c7565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212202c0f04376c092424b843087e46d06977a9a71e7825053fcd2b1d9e6c0b0dc56d64736f6c63430006070033

Verified Source Code Partial Match

Compiler: v0.6.7+commit.b8d736ae EVM: istanbul Optimization: No
VSCToken.sol 1117 lines
// File: contracts/thirdParty/ECDSA.sol

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/cryptography/ECDSA.sol
// Line 60 added to original source in accordance with recommendation on accepting signatures with 0/1 for v

pragma solidity ^0.6.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Check the signature length
        if (signature.length != 65) {
            revert("ECDSA: invalid signature length");
        }

        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            r := mload(add(signature, 0x20))
            s := mload(add(signature, 0x40))
            v := byte(0, mload(add(signature, 0x60)))
        }

        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            revert("ECDSA: invalid signature 's' value");
        }

        if (v < 27) v += 27;

        if (v != 27 && v != 28) {
            revert("ECDSA: invalid signature 'v' value");
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: invalid signature");

        return signer;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * replicates the behavior of the
     * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
     * JSON-RPC method.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }
}

// File: contracts/interfaces/IERC777.sol

pragma solidity 0.6.7;

// As defined in https://eips.ethereum.org/EIPS/eip-777
interface IERC777 {
  event Sent(address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data,
      bytes operatorData);
  event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
  event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
  event AuthorizedOperator(address indexed operator,address indexed holder);
  event RevokedOperator(address indexed operator, address indexed holder);

  function name() external view returns (string memory);
  function symbol() external view returns (string memory);
  function totalSupply() external view returns (uint256);
  function balanceOf(address holder) external view returns (uint256);
  function granularity() external view returns (uint256);
  function defaultOperators() external view returns (address[] memory);
  function isOperatorFor(address operator, address holder) external view returns (bool);
  function authorizeOperator(address operator) external;
  function revokeOperator(address operator) external;
  function send(address to, uint256 amount, bytes calldata data) external;
  function operatorSend(address from, address to, uint256 amount, bytes calldata data, bytes calldata operatorData) external;
  function burn(uint256 amount, bytes calldata data) external;
  function operatorBurn( address from, uint256 amount, bytes calldata data, bytes calldata operatorData) external;
}

// File: contracts/interfaces/IERC20.sol

pragma solidity 0.6.7;

// As described in https://eips.ethereum.org/EIPS/eip-20
interface IERC20 {
  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);

  function name() external view returns (string memory); // optional method - see eip spec
  function symbol() external view returns (string memory); // optional method - see eip spec
  function decimals() external view returns (uint8); // optional method - see eip spec
  function totalSupply() external view returns (uint256);
  function balanceOf(address owner) external view returns (uint256);
  function transfer(address to, uint256 value) external returns (bool);
  function transferFrom(address from, address to, uint256 value) external returns (bool);
  function approve(address spender, uint256 value) external returns (bool);
  function allowance(address owner, address spender) external view returns (uint256);
}

// File: contracts/thirdParty/interfaces/IERC1820Registry.sol

// From open https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/introspection/IERC1820Registry.sol

pragma solidity ^0.6.0;

/**
 * @dev Interface of the global ERC1820 Registry, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
 * implementers for interfaces in this registry, as well as query support.
 *
 * Implementers may be shared by multiple accounts, and can also implement more
 * than a single interface for each account. Contracts can implement interfaces
 * for themselves, but externally-owned accounts (EOA) must delegate this to a
 * contract.
 *
 * {IERC165} interfaces can also be queried via the registry.
 *
 * For an in-depth explanation and source code analysis, see the EIP text.
 */
interface IERC1820Registry {
    /**
     * @dev Sets `newManager` as the manager for `account`. A manager of an
     * account is able to set interface implementers for it.
     *
     * By default, each account is its own manager. Passing a value of `0x0` in
     * `newManager` will reset the manager to this initial state.
     *
     * Emits a {ManagerChanged} event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     */
    function setManager(address account, address newManager) external;

    /**
     * @dev Returns the manager for `account`.
     *
     * See {setManager}.
     */
    function getManager(address account) external view returns (address);

    /**
     * @dev Sets the `implementer` contract as ``account``'s implementer for
     * `interfaceHash`.
     *
     * `account` being the zero address is an alias for the caller's address.
     * The zero address can also be used in `implementer` to remove an old one.
     *
     * See {interfaceHash} to learn how these are created.
     *
     * Emits an {InterfaceImplementerSet} event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not
     * end in 28 zeroes).
     * - `implementer` must implement {IERC1820Implementer} and return true when
     * queried for support, unless `implementer` is the caller. See
     * {IERC1820Implementer-canImplementInterfaceForAddress}.
     */
    function setInterfaceImplementer(address account, bytes32 interfaceHash, address implementer) external;

    /**
     * @dev Returns the implementer of `interfaceHash` for `account`. If no such
     * implementer is registered, returns the zero address.
     *
     * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
     * zeroes), `account` will be queried for support of it.
     *
     * `account` being the zero address is an alias for the caller's address.
     */
    function getInterfaceImplementer(address account, bytes32 interfaceHash) external view returns (address);

    /**
     * @dev Returns the interface hash for an `interfaceName`, as defined in the
     * corresponding
     * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
     */
    function interfaceHash(string calldata interfaceName) external pure returns (bytes32);

    /**
     *  @notice Updates the cache with whether the contract implements an ERC165 interface or not.
     *  @param account Address of the contract for which to update the cache.
     *  @param interfaceId ERC165 interface for which to update the cache.
     */
    function updateERC165Cache(address account, bytes4 interfaceId) external;

    /**
     *  @notice Checks whether a contract implements an ERC165 interface or not.
     *  If the result is not cached a direct lookup on the contract address is performed.
     *  If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
     *  {updateERC165Cache} with the contract address.
     *  @param account Address of the contract to check.
     *  @param interfaceId ERC165 interface to check.
     *  @return True if `account` implements `interfaceId`, false otherwise.
     */
    function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);

    /**
     *  @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
     *  @param account Address of the contract to check.
     *  @param interfaceId ERC165 interface to check.
     *  @return True if `account` implements `interfaceId`, false otherwise.
     */
    function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);

    event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);

    event ManagerChanged(address indexed account, address indexed newManager);
}

// File: contracts/interfaces/IERC777Sender.sol

pragma solidity 0.6.7;

// As defined in the 'ERC777TokensSender And The tokensToSend Hook' section of https://eips.ethereum.org/EIPS/eip-777
interface IERC777Sender {
  function tokensToSend(address operator, address from, address to, uint256 amount, bytes calldata data,
      bytes calldata operatorData) external;
}

// File: contracts/interfaces/IERC777Recipient.sol

pragma solidity 0.6.7;

// As defined in the 'ERC777TokensRecipient And The tokensReceived Hook' section of https://eips.ethereum.org/EIPS/eip-777
interface IERC777Recipient {
  function tokensReceived(address operator, address from, address to, uint256 amount, bytes calldata data,
      bytes calldata operatorData) external;
}

// File: contracts/thirdParty/SafeMath.sol

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol

pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// File: contracts/libraries/LToken.sol

pragma solidity 0.6.7;





struct TokenState {
  uint256 totalSupply;
  mapping(address => uint256) balances;
  mapping(address => mapping(address => uint256)) approvals;
  mapping(address => mapping(address => bool)) authorizedOperators;
  address[] defaultOperators;
  mapping(address => bool) defaultOperatorIsRevoked;
  mapping(address => bool) minters;
}

library LToken {
  using SafeMath for uint256;

  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);
  event Sent(address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data,
      bytes operatorData);
  event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
  event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
  event AuthorizedOperator(address indexed operator, address indexed holder);
  event RevokedOperator(address indexed operator, address indexed holder);

  // Universal address as defined in Registry Contract Address section of https://eips.ethereum.org/EIPS/eip-1820
  IERC1820Registry constant internal ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
  // precalculated hashes - see https://github.com/ethereum/solidity/issues/4024
  // keccak256("ERC777TokensSender")
  bytes32 constant internal ERC777_TOKENS_SENDER_HASH = 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;
  // keccak256("ERC777TokensRecipient")
  bytes32 constant internal ERC777_TOKENS_RECIPIENT_HASH = 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;

  modifier checkSenderNotOperator(address _operator) {
    require(_operator != msg.sender, "Cannot be operator for self");
    _;
  }

  function initState(TokenState storage _tokenState, uint8 _decimals, uint256 _initialSupply)
    external
  {
    _tokenState.defaultOperators.push(address(this));
    _tokenState.totalSupply = _initialSupply.mul(10**uint256(_decimals));
    _tokenState.balances[msg.sender] = _tokenState.totalSupply;
  }

  function transferFrom(TokenState storage _tokenState, address _from, address _to, uint256 _value)
    external
  {
    _tokenState.approvals[_from][msg.sender] = _tokenState.approvals[_from][msg.sender].sub(_value, "Amount not approved");
    doSend(_tokenState, msg.sender, _from, _to, _value, "", "", false);
  }

  function approve(TokenState storage _tokenState, address _spender, uint256 _value)
    external
  {
    require(_spender != address(0), "Cannot approve to zero address");
    _tokenState.approvals[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
  }

  function authorizeOperator(TokenState storage _tokenState, address _operator)
    checkSenderNotOperator(_operator)
    external
  {
    if (_operator == address(this))
      _tokenState.defaultOperatorIsRevoked[msg.sender] = false;
    else
      _tokenState.authorizedOperators[_operator][msg.sender] = true;
    emit AuthorizedOperator(_operator, msg.sender);
  }

  function revokeOperator(TokenState storage _tokenState, address _operator)
    checkSenderNotOperator(_operator)
    external
  {
    if (_operator == address(this))
      _tokenState.defaultOperatorIsRevoked[msg.sender] = true;
    else
      _tokenState.authorizedOperators[_operator][msg.sender] = false;
    emit RevokedOperator(_operator, msg.sender);
  }

  function authorizeMinter(TokenState storage _tokenState, address _minter)
    external
  {
    _tokenState.minters[_minter] = true;
  }

  function revokeMinter(TokenState storage _tokenState, address _minter)
    external
  {
    _tokenState.minters[_minter] = false;
  }

  function doMint(TokenState storage _tokenState, address _to, uint256 _amount)
    external
  {
    assert(_to != address(0));

    _tokenState.totalSupply = _tokenState.totalSupply.add(_amount);
    _tokenState.balances[_to] = _tokenState.balances[_to].add(_amount);

    // From ERC777: The token contract MUST call the tokensReceived hook after updating the state.
    receiveHook(address(this), address(0), _to, _amount, "", "", true);

    emit Minted(address(this), _to, _amount, "", "");
    emit Transfer(address(0), _to, _amount);
  }

  function doBurn(TokenState storage _tokenState, address _operator, address _from, uint256 _amount, bytes calldata _data,
      bytes calldata _operatorData)
    external
  {
    assert(_from != address(0));
    // From ERC777: The token contract MUST call the tokensToSend hook before updating the state.
    sendHook(_operator, _from, address(0), _amount, _data, _operatorData);

    _tokenState.balances[_from] = _tokenState.balances[_from].sub(_amount, "Cannot burn more than balance");
    _tokenState.totalSupply = _tokenState.totalSupply.sub(_amount);

    emit Burned(_operator, _from, _amount, _data, _operatorData);
    emit Transfer(_from, address(0), _amount);
  }

  function doSend(TokenState storage _tokenState, address _operator, address _from, address _to, uint256 _amount,
      bytes memory _data, bytes memory _operatorData, bool _enforceERC777)
    public
  {
    assert(_from != address(0));

    require(_to != address(0), "Cannot send funds to 0 address");
    // From ERC777: The token contract MUST call the tokensToSend hook before updating the state.
    sendHook(_operator, _from, _to, _amount, _data, _operatorData);

    _tokenState.balances[_from] = _tokenState.balances[_from].sub(_amount, "Amount exceeds available funds");
    _tokenState.balances[_to] = _tokenState.balances[_to].add(_amount);

    emit Sent(_operator, _from, _to, _amount, _data, _operatorData);
    emit Transfer(_from, _to, _amount);

    // From ERC777: The token contract MUST call the tokensReceived hook after updating the state.
    receiveHook(_operator, _from, _to, _amount, _data, _operatorData, _enforceERC777);
  }

  function receiveHook(address _operator, address _from, address _to, uint256 _amount, bytes memory _data,
      bytes memory _operatorData, bool _enforceERC777)
    public
  {
    address implementer = ERC1820_REGISTRY.getInterfaceImplementer(_to, ERC777_TOKENS_RECIPIENT_HASH);
    if (implementer != address(0))
      IERC777Recipient(implementer).tokensReceived(_operator, _from, _to, _amount, _data, _operatorData);
    else if (_enforceERC777)
      require(!isContract(_to), "Must be registered with ERC1820");
  }

  function sendHook(address _operator, address _from, address _to, uint256 _amount, bytes memory _data,
      bytes memory _operatorData)
    public
  {
    address implementer = ERC1820_REGISTRY.getInterfaceImplementer(_from, ERC777_TOKENS_SENDER_HASH);
    if (implementer != address(0))
      IERC777Sender(implementer).tokensToSend(_operator, _from, _to, _amount, _data, _operatorData);
  }

  function isContract(address _account)
    private
    view
    returns (bool isContract_)
  {
    uint256 size;

    assembly {
      size := extcodesize(_account)
    }

    isContract_ = size != 0;
  }
}

// File: contracts/Token.sol

pragma solidity 0.6.7;




/**
 * Implements ERC777 with ERC20 as defined in https://eips.ethereum.org/EIPS/eip-777, with minting support.
 * NOTE: Minting is internal only: derive from this contract according to usage.
 */
contract Token is IERC777, IERC20 {

  string private tokenName;
  string private tokenSymbol;
  uint8 constant private tokenDecimals = 18;
  uint256 constant private tokenGranularity = 1;
  TokenState public tokenState;

  // Universal address as defined in Registry Contract Address section of https://eips.ethereum.org/EIPS/eip-1820
  IERC1820Registry constant internal ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
  // keccak256("ERC777Token")
  bytes32 constant internal ERC777_TOKEN_HASH = 0xac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce2177054;
  // keccak256("ERC20Token")
  bytes32 constant internal ERC20_TOKEN_HASH = 0xaea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a;

  event AuthorizedMinter(address minter);
  event RevokedMinter(address minter);

  constructor(string memory _name, string memory _symbol, uint256 _initialSupply)
    internal
  {
    require(bytes(_name).length != 0, "Needs a name");
    require(bytes(_symbol).length != 0, "Needs a symbol");
    tokenName = _name;
    tokenSymbol = _symbol;
    LToken.initState(tokenState, tokenDecimals, _initialSupply);

    ERC1820_REGISTRY.setInterfaceImplementer(address(this), ERC777_TOKEN_HASH, address(this));
    ERC1820_REGISTRY.setInterfaceImplementer(address(this), ERC20_TOKEN_HASH, address(this));
  }

  modifier onlyOperator(address _holder) {
    require(isOperatorFor(msg.sender, _holder), "Not an operator");
    _;
  }

  modifier onlyMinter {
    require(tokenState.minters[msg.sender], "onlyMinter");
    _;
  }

  function name()
    external
    view
    override(IERC777, IERC20)
    returns (string memory name_)
  {
    name_ = tokenName;
  }

  function symbol()
    external
    view
    override(IERC777, IERC20)
    returns (string memory symbol_)
  {
    symbol_ = tokenSymbol;
  }

  function decimals()
    external
    view
    override
    returns (uint8 decimals_)
  {
    decimals_ = tokenDecimals;
  }

  function granularity()
    external
    view
    override
    returns (uint256 granularity_)
  {
    granularity_ = tokenGranularity;
  }

  function balanceOf(address _holder)
    external
    override(IERC777, IERC20)
    view
    returns (uint256 balance_)
  {
    balance_ = tokenState.balances[_holder];
  }

  function transfer(address _to, uint256 _value)
    external
    override
    returns (bool success_)
  {
    doSend(msg.sender, msg.sender, _to, _value, "", "", false);
    success_ = true;
  }

  function transferFrom(address _from, address _to, uint256 _value)
    external
    override
    returns (bool success_)
  {
    LToken.transferFrom(tokenState, _from, _to, _value);
    success_ = true;
  }

  function approve(address _spender, uint256 _value)
    external
    override
    returns (bool success_)
  {
    LToken.approve(tokenState, _spender, _value);
    success_ = true;
  }

  function allowance(address _holder, address _spender)
    external
    view
    override
    returns (uint256 remaining_)
  {
    remaining_ = tokenState.approvals[_holder][_spender];
  }

  function defaultOperators()
    external
    view
    override
    returns (address[] memory)
  {
    return tokenState.defaultOperators;
  }

  function authorizeOperator(address _operator)
    external
    override
  {
    LToken.authorizeOperator(tokenState, _operator);
  }

  function revokeOperator(address _operator)
    external
    override
  {
    LToken.revokeOperator(tokenState, _operator);
  }

  function send(address _to, uint256 _amount, bytes calldata _data)
    external
    override
  {
    doSend(msg.sender, msg.sender, _to, _amount, _data, "", true);
  }

  function operatorSend(address _from, address _to, uint256 _amount, bytes calldata _data, bytes calldata _operatorData)
    external
    override
    onlyOperator(_from)
  {
    doSend(msg.sender, _from, _to, _amount, _data, _operatorData, true);
  }

  function burn(uint256 _amount, bytes calldata _data)
    external
    override
  {
    doBurn(msg.sender, msg.sender, _amount, _data, "");
  }

  function operatorBurn(address _from, uint256 _amount, bytes calldata _data, bytes calldata _operatorData)
    external
    override
    onlyOperator(_from)
  {
    doBurn(msg.sender, _from, _amount, _data, _operatorData);
  }

  function mint(address _to, uint256 _amount)
    external
    onlyMinter
  {
    LToken.doMint(tokenState, _to, _amount);
  }

  function totalSupply()
    external
    view
    override(IERC777, IERC20)
    returns (uint256 totalSupply_)
  {
    totalSupply_ = tokenState.totalSupply;
  }

  function isOperatorFor(address _operator, address _holder)
    public
    view
    override
    returns (bool isOperatorFor_)
  {
    isOperatorFor_ = (_operator == _holder || tokenState.authorizedOperators[_operator][_holder]
        || _operator == address(this) && !tokenState.defaultOperatorIsRevoked[_holder]);
  }

  function doSend(address _operator, address _from, address _to, uint256 _amount, bytes memory _data,
      bytes memory _operatorData, bool _enforceERC777)
    internal
    virtual
  {
    LToken.doSend(tokenState, _operator, _from, _to, _amount, _data, _operatorData, _enforceERC777);
  }

  function doBurn(address _operator, address _from, uint256 _amount, bytes memory _data, bytes memory _operatorData)
    internal
  {
    LToken.doBurn(tokenState, _operator, _from, _amount, _data, _operatorData);
  }

  function authorizeMinter(address _minter)
    internal
  {
    LToken.authorizeMinter(tokenState, _minter);

    emit AuthorizedMinter(_minter);
  }

  function revokeMinter(address _minter)
    internal
  {
    LToken.revokeMinter(tokenState, _minter);

    emit RevokedMinter(_minter);
  }
}

// File: contracts/Owned.sol

pragma solidity 0.6.7;

contract Owned {

  address public owner = msg.sender;

  event LogOwnershipTransferred(address indexed owner, address indexed newOwner);

  modifier onlyOwner {
    require(msg.sender == owner, "Sender must be owner");
    _;
  }

  function setOwner(address _owner)
    external
    onlyOwner
  {
    require(_owner != address(0), "Owner cannot be zero address");
    emit LogOwnershipTransferred(owner, _owner);
    owner = _owner;
  }
}

// File: contracts/VOWToken.sol

pragma solidity 0.6.7;




/**
 * ERC777/20 contract which also:
 * - is owned
 * - supports proxying of own tokens (only if signed correctly)
 * - supports partner contracts, keyed by hash
 * - supports minting (only by owner approved contracts)
 * - has a USD price
 */
contract VOWToken is Token, IERC777Recipient, Owned {

  mapping (bytes32 => bool) public proxyProofs;
  uint256[2] public usdRate;
  address public usdRateSetter;
  mapping(bytes32 => address payable) public partnerContracts;

  // precalculated hash - see https://github.com/ethereum/solidity/issues/4024
  // keccak256("ERC777TokensRecipient")
  bytes32 constant internal ERC777_TOKENS_RECIPIENT_HASH = 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;

  event LogUSDRateSetterSet(address indexed usdRateSetter);
  event LogUSDRateSet(uint256 numTokens, uint256 numUSD);
  event LogProxiedTokens(address indexed from, address indexed to, uint256 amount, bytes data, uint256 nonce, bytes proof);
  event LogPartnerContractSet(bytes32 indexed keyHash, address indexed partnerContract);
  event LogMintPermissionSet(address indexed contractAddress, bool canMint);

  constructor(string memory _name, string memory _symbol, uint256 _initialSupply, uint256[2] memory _initialUSDRate)
    public
    Token(_name, _symbol, _initialSupply)
  {
    doSetUSDRate(_initialUSDRate[0], _initialUSDRate[1]);

    ERC1820_REGISTRY.setInterfaceImplementer(address(this), ERC777_TOKENS_RECIPIENT_HASH, address(this));
  }

  modifier onlyUSDRateSetter() {
    require(msg.sender == usdRateSetter, "onlyUSDRateSetter");
    _;
  }

  modifier onlyOwnTokens {
    require(msg.sender == address(this), "onlyOwnTokens");
    _;
  }

  modifier addressNotNull(address _address) {
    require(_address != address(0), "Address cannot be null");
    _;
  }

  function tokensReceived(address /* _operator */, address /* _from */, address /* _to */, uint256 _amount,
      bytes calldata _data, bytes calldata /* _operatorData */)
    external
    override
    onlyOwnTokens
  {
    (address from, address to, uint256 amount, bytes memory data, uint256 nonce, bytes memory proof) =
        abi.decode(_data, (address, address, uint256, bytes, uint256, bytes));
    checkProxying(from, to, amount, data, nonce, proof);

    if (_amount != 0)
      this.send(from, _amount, "");

    this.operatorSend(from, to, amount, data, _data);

    emit LogProxiedTokens(from, to, amount, data, nonce, proof);
  }

  function setPartnerContract(bytes32 _keyHash, address payable _partnerContract)
    external
    onlyOwner
    addressNotNull(_partnerContract)
  {
    require(_keyHash != bytes32(0), "Missing key hash");
    partnerContracts[_keyHash] = _partnerContract;

    emit LogPartnerContractSet(_keyHash, _partnerContract);
  }

  function setUSDRateSetter(address _usdRateSetter)
    external
    onlyOwner
    addressNotNull(_usdRateSetter)
  {
    usdRateSetter = _usdRateSetter;

    emit LogUSDRateSetterSet(_usdRateSetter);
  }

  function setUSDRate(uint256 _numTokens, uint256 _numUSD)
    external
    onlyUSDRateSetter
  {
    doSetUSDRate(_numTokens, _numUSD);

    emit LogUSDRateSet(_numTokens, _numUSD);
  }

  function setMintPermission(address _contract, bool _canMint)
    external
    onlyOwner
    addressNotNull(_contract)
  {
    if (_canMint)
      authorizeMinter(_contract);
    else
      revokeMinter(_contract);

    emit LogMintPermissionSet(_contract, _canMint);
  }

  function doSetUSDRate(uint256 _numTokens, uint256 _numUSD)
    private
  {
    require(_numTokens != 0, "numTokens cannot be zero");
    require(_numUSD != 0, "numUSD cannot be zero");
    usdRate = [_numTokens, _numUSD];
  }

  function checkProxying(address _from, address _to, uint256 _amount, bytes memory _data, uint256 _nonce, bytes memory _proof)
    private
  {
    require(!proxyProofs[keccak256(_proof)], "Proxy proof not unique");
    proxyProofs[keccak256(_proof)] = true;
    bytes32 hash = keccak256(abi.encodePacked(address(this), _from, _to, _amount, _data, _nonce));
    address signer = ECDSA.recover(ECDSA.toEthSignedMessageHash(hash), _proof);
    require(signer == _from, "Bad signer");
  }
}

// File: contracts/VSCToken.sol

pragma solidity 0.6.7;


/**
 * VSCToken is a VOWToken with:
 * - a linked parent Vow token
 * - tier 1 burn (with owner aproved exceptions)
 * - tier 2 delegated lifting (only by owner approved contracts)
 */
contract VSCToken is VOWToken {
  using SafeMath for uint256;

  address public immutable vowContract;
  mapping(address => bool) public canLift;
  mapping(address => bool) public skipTier1Burn;
  uint256[2] public tier1BurnVSC;

  event LogTier1BurnVSCUpdated(uint256[2] ratio);
  event LogLiftPermissionSet(address indexed liftingAddress, bool canLift);
  event LogSkipTier1BurnSet(address indexed skipTier1BurnAddress, bool skipTier1Burn);

  constructor(string memory _name, string memory _symbol, uint256[2] memory _initialVSCUSD, address _vowContract)
    VOWToken(_name, _symbol, 0, _initialVSCUSD)
    public
  {
    vowContract = _vowContract;

    ERC1820_REGISTRY.setInterfaceImplementer(address(this), ERC777_TOKENS_RECIPIENT_HASH, address(this));

    tier1BurnVSC = [0, 1]; // Default to no burn: ie burn 0 VSC for every 1 VSC sent on tier 1

    setSkipTier1Burn(address(this), true);
  }

  modifier onlyLifter() {
    require(canLift[msg.sender], "onlyLifter");
    _;
  }

  function setLiftPermission(address _liftingAddress, bool _canLift)
    external
    onlyOwner
    addressNotNull(_liftingAddress)
  {
    canLift[_liftingAddress] = _canLift;

    emit LogLiftPermissionSet(_liftingAddress, _canLift);
  }

  function setTier1BurnVSC(uint256 _numVSCBurned, uint256 _numVSCSent)
    external
    onlyOwner
  {
    require(_numVSCSent != 0, "Invalid burn ratio: div by zero");
    require(_numVSCSent >= _numVSCBurned, "Invalid burn ratio: above 100%");
    tier1BurnVSC = [_numVSCBurned, _numVSCSent];

    emit LogTier1BurnVSCUpdated(tier1BurnVSC);
  }

  function lift(address _liftAccount, uint256 _amount, bytes calldata _data)
    external
    onlyLifter
  {
    address tier2ScalingManager = partnerContracts[keccak256(abi.encodePacked("FTScalingManager"))];
    this.operatorSend(_liftAccount, tier2ScalingManager, _amount , _data, "");
  }

  function setSkipTier1Burn(address _skipTier1BurnAddress, bool _skipTier1Burn)
    public
    onlyOwner
    addressNotNull(_skipTier1BurnAddress)
  {
    skipTier1Burn[_skipTier1BurnAddress] = _skipTier1Burn;

    emit LogSkipTier1BurnSet(_skipTier1BurnAddress, _skipTier1Burn);
  }

  function doSend(address _operator, address _from, address _to, uint256 _amount, bytes memory _data,
      bytes memory _operatorData, bool _enforceERC777)
    internal
    virtual
    override
  {
    uint256 actualSendAmount = _amount;

    if (!skipTier1Burn[_from] && !skipTier1Burn[_to]) {
      uint256 burnAmount = _amount.mul(tier1BurnVSC[0]).div(tier1BurnVSC[1]);
      doBurn(_operator, _from, burnAmount, _data, _operatorData);
      actualSendAmount = actualSendAmount.sub(burnAmount);
    }
    super.doSend(_operator, _from, _to, actualSendAmount, _data, _operatorData, _enforceERC777);
  }
}

Read Contract

allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
canLift 0xb2beab03 → bool
decimals 0x313ce567 → uint8
defaultOperators 0x06e48538 → address[]
granularity 0x556f0dc7 → uint256
isOperatorFor 0xd95b6371 → bool
name 0x06fdde03 → string
owner 0x8da5cb5b → address
partnerContracts 0xa9f83f82 → address
proxyProofs 0x8dfdd8a1 → bool
skipTier1Burn 0xe186719e → bool
symbol 0x95d89b41 → string
tier1BurnVSC 0xd84a25b7 → uint256
tokenState 0xe90dd9e2 → uint256
totalSupply 0x18160ddd → uint256
usdRate 0x6f54ed75 → uint256
usdRateSetter 0xb89f378a → address
vowContract 0x1171ffcf → address

Write Contract 20 functions

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

approve 0x095ea7b3
address _spender
uint256 _value
returns: bool
authorizeOperator 0x959b8c3f
address _operator
burn 0xfe9d9303
uint256 _amount
bytes _data
lift 0xfbd7d752
address _liftAccount
uint256 _amount
bytes _data
mint 0x40c10f19
address _to
uint256 _amount
operatorBurn 0xfc673c4f
address _from
uint256 _amount
bytes _data
bytes _operatorData
operatorSend 0x62ad1b83
address _from
address _to
uint256 _amount
bytes _data
bytes _operatorData
revokeOperator 0xfad8b32a
address _operator
send 0x9bd9bbc6
address _to
uint256 _amount
bytes _data
setLiftPermission 0xc6eb68fa
address _liftingAddress
bool _canLift
setMintPermission 0xa04b1e90
address _contract
bool _canMint
setOwner 0x13af4035
address _owner
setPartnerContract 0x6eac7739
bytes32 _keyHash
address _partnerContract
setSkipTier1Burn 0x7de891d6
address _skipTier1BurnAddress
bool _skipTier1Burn
setTier1BurnVSC 0xdb078449
uint256 _numVSCBurned
uint256 _numVSCSent
setUSDRate 0x3c858577
uint256 _numTokens
uint256 _numUSD
setUSDRateSetter 0xe47fca4e
address _usdRateSetter
tokensReceived 0x0023de29
address
address
address
uint256 _amount
bytes _data
bytes
transfer 0xa9059cbb
address _to
uint256 _value
returns: bool
transferFrom 0x23b872dd
address _from
address _to
uint256 _value
returns: bool

Recent Transactions

No transactions found for this address