Address Contract Verified
Address
0x5Fa19F612dfd39e6754Bb2E8300E681d1C589Dd4
Balance
0 ETH
Nonce
1
Code Size
23427 bytes
Creator
0x6d2e9BAe...4031 at tx 0x7409b716...11ff26
Indexed Transactions
0 (1 on-chain, 1.1% indexed)
Contract Bytecode
23427 bytes
0x608060405234801561001057600080fd5b50600436106102f15760003560e01c806361d027b31161019d578063a230c524116100e9578063e4ebdfa5116100a2578063ed06d4e21161007c578063ed06d4e21461132e578063f525cb68146113b4578063f96e9ea1146113d2578063fa8f382a14611434576102f1565b8063e4ebdfa5146111ec578063eb76595514611268578063ec7d7199146112d6576102f1565b8063a230c52414610fec578063baff15ce14611048578063c251adeb146110b6578063ce110e4b14611100578063ddd5e1b214611158578063e07dbfbd146111a6576102f1565b806378a45a241161015657806387e2662e1161013057806387e2662e14610e965780638b5e608b14610ef2578063973628f614610f4a578063a19d164614610f68576102f1565b806378a45a2414610dd85780637f2277b414610df6578063845696b414610e52576102f1565b806361d027b314610c1457806369b3039814610c5e5780636ea056a914610cb45780637048027514610d0257806371586b1f14610d4657806375829def14610d94576102f1565b8063322e26041161025c5780634445c1ea116102155780634a5cab98116101ef5780634a5cab9814610a885780634dd85b5e14610ad6578063522cff2514610b385780635976c67c14610b90576102f1565b80634445c1ea1461093657806344d3d337146109a457806344d7e45514610a06576102f1565b8063322e26041461067057806332bc68be146106d25780633d23e24a146107405780633e66034f146107b8578063429d7e8f1461083a578063436f80be146108c8576102f1565b8063282d3fdf116102ae578063282d3fdf146104b45780632b7832b3146105025780632f6c493c14610520578063306faf4a1461056457806331405c03146105a85780633224e2f21461060e576102f1565b80630382ad26146102f657806311aee3801461035857806316d534711461037657806324d7806c146103d2578063265121601461042e57806326b8052914610472575b600080fd5b6103426004803603604081101561030c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114c2565b6040518082815260200191505060405180910390f35b6103606115b1565b6040518082815260200191505060405180910390f35b6103b86004803603602081101561038c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115be565b604051808215151515815260200191505060405180910390f35b610414600480360360208110156103e857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115de565b604051808215151515815260200191505060405180910390f35b6104706004803603602081101561044457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115fe565b005b61049e6004803603602081101561048857600080fd5b81019080803590602001909291905050506116e8565b6040518082815260200191505060405180910390f35b610500600480360360408110156104ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611700565b005b61050a611f4e565b6040518082815260200191505060405180910390f35b6105626004803603602081101561053657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f5b565b005b6105a66004803603602081101561057a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612416565b005b6105f4600480360360408110156105be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612530565b604051808215151515815260200191505060405180910390f35b61066e6004803603608081101561062457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061255f565b005b6106bc6004803603604081101561068657600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a3b565b6040518082815260200191505060405180910390f35b6106fe600480360360208110156106e857600080fd5b8101908080359060200190929190505050612a60565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107a26004803603604081101561075657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a9c565b6040518082815260200191505060405180910390f35b610824600480360360608110156107ce57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ac1565b6040518082815260200191505060405180910390f35b6108c66004803603608081101561085057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612c2b565b005b6108f4600480360360208110156108de57600080fd5b8101908080359060200190929190505050612f42565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109626004803603602081101561094c57600080fd5b8101908080359060200190929190505050612f7e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109f0600480360360408110156109ba57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612fba565b6040518082815260200191505060405180910390f35b610a7260048036036060811015610a1c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612fdf565b6040518082815260200191505060405180910390f35b610ad460048036036040811015610a9e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613011565b005b610b2260048036036040811015610aec57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506130f3565b6040518082815260200191505060405180910390f35b610b7a60048036036020811015610b4e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613118565b6040518082815260200191505060405180910390f35b610bd260048036036020811015610ba657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613130565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c1c613163565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c9e60048036036060811015610c7457600080fd5b81019080803590602001909291908035906020019092919080359060200190929190505050613189565b6040518082815260200191505060405180910390f35b610d0060048036036040811015610cca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506131b9565b005b610d4460048036036020811015610d1857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506133d2565b005b610d9260048036036040811015610d5c57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061364e565b005b610dd660048036036020811015610daa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506139d4565b005b610de0613ca8565b6040518082815260200191505060405180910390f35b610e3860048036036020811015610e0c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613cb5565b604051808215151515815260200191505060405180910390f35b610e9460048036036020811015610e6857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613cd5565b005b610ed860048036036020811015610eac57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614257565b604051808215151515815260200191505060405180910390f35b610f3460048036036020811015610f0857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614277565b6040518082815260200191505060405180910390f35b610f5261428f565b6040518082815260200191505060405180910390f35b610faa60048036036020811015610f7e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614295565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61102e6004803603602081101561100257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506142c8565b604051808215151515815260200191505060405180910390f35b6110b46004803603606081101561105e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506142e8565b005b6110be6147ed565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6111426004803603602081101561111657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614813565b6040518082815260200191505060405180910390f35b6111a46004803603604081101561116e57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061482b565b005b6111d2600480360360208110156111bc57600080fd5b8101908080359060200190929190505050614e46565b604051808215151515815260200191505060405180910390f35b61124e6004803603604081101561120257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614e66565b604051808215151515815260200191505060405180910390f35b6112946004803603602081101561127e57600080fd5b8101908080359060200190929190505050614e95565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61132c600480360360608110156112ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050614ed1565b005b61139a6004803603606081101561134457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614fbf565b604051808215151515815260200191505060405180910390f35b6113bc614ffb565b6040518082815260200191505060405180910390f35b61141e600480360360408110156113e857600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615008565b6040518082815260200191505060405180910390f35b6114806004803603604081101561144a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061502d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600080600090505b601760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548110156115a7576000601860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061155d57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050611595858583612ac1565b830192505080806001019150506114ca565b5080905092915050565b6000600680549050905090565b600b6020528060005260406000206000915054906101000a900460ff1681565b60086020528060005260406000206000915054906101000a900460ff1681565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166116bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b6116c981600754613011565b6116df600160075461507890919063ffffffff16565b60078190555050565b600e6020528060005260406000206000915090505481565b60026000541415611779576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260008190555060011515600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514611847576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f4d757374206265206c697374656400000000000000000000000000000000000081525060200191505060405180910390fd5b601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611954576006339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166119fe576001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b601a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611c5857611adf6001601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461507890919063ffffffff16565b601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001601a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611d1357600080fd5b505af1158015611d27573d6000803e3d6000fd5b505050506040513d6020811015611d3d57600080fd5b8101908080519060200190929190505050611dc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d757374207472616e736665720000000000000000000000000000000000000081525060200191505060405180910390fd5b611e4f81601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461507890919063ffffffff16565b601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611eda338383615100565b6007548273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f26c1d455ed5e9a313ff262b6cd70a49110f54a2a68591881424ade0176624983846040518082815260200191505060405180910390a460016000819055505050565b6000600380549050905090565b60026000541415611fd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055506000601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081116120d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4d757374206861766520612062616c616e636520746f20636c61696d0000000081525060200191505060405180910390fd5b6000601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156121dc57600080fd5b505af11580156121f0573d6000803e3d6000fd5b505050506040513d602081101561220657600080fd5b8101908080519060200190929190505050612289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d757374207472616e736665720000000000000000000000000000000000000081525060200191505060405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561230857600080fd5b505afa15801561231c573d6000803e3d6000fd5b505050506040513d602081101561233257600080fd5b810190808051906020019092919050505014156123a2576000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b6007548273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffc457b903eae2c3f6e2d259cccaae44e68f974c0c77dda2f7877aa4ed140d5c6846040518082815260200191505060405180910390a450600160008190555050565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166124d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b601b6020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661261e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156126c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f41646472657373206d757374206e6f742062652030783000000000000000000081525060200191505060405180910390fd5b60016007540383101580156126d857506007548311155b61272d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615b2a6024913960400191505060405180910390fd5b6000612838600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156127ef57600080fd5b505afa158015612803573d6000803e3d6000fd5b505050506040513d602081101561281957600080fd5b81019080805190602001909291905050506152c590919063ffffffff16565b9050600081116128b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f416d6f756e74206d757374206265206e6f6e2d7a65726f00000000000000000081525060200191505060405180910390fd5b61290281600c60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461507890919063ffffffff16565b600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506129a8816010600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461507890919063ffffffff16565b6010600086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001600f600086815260200190815260200160002060006101000a81548160ff021916908315150217905550612a348482858561530f565b5050505050565b6012602052816000526040600020602052806000526040600020600091509150505481565b60048181548110612a6d57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6019602052816000526040600020602052806000526040600020600091509150505481565b6000806012600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000601c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006013600087815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000811115612c1957612c12828285613189565b9350612c1e565b600093505b8393505050509392505050565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612cea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612d8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4d757374207061737320616464726573732076616c69646174696f6e0000000081525060200191505060405180910390fd5b600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612e42576005839080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b612e4d8484836142e8565b81601560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f4e351dd0f3a8cc5682178a81d960be19d454f9fe874a9d4f0753caae5685900060405160405180910390a450505050565b60068181548110612f4f57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60038181548110612f8b57fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6010602052816000526040600020602052806000526040600020600091509150505481565b601c60205282600052604060002060205281600052604060002060205280600052604060002060009250925050505481565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166130d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b600080905060006130df614ffb565b90506130ed8484848461255f565b50505050565b6011602052816000526040600020602052806000526040600020600091509150505481565b600c6020528060005260406000206000915090505481565b60156020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006131b0836131a2868561583990919063ffffffff16565b6158bf90919063ffffffff16565b90509392505050565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16613278576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561332157600080fd5b505af1158015613335573d6000803e3d6000fd5b505050506040513d602081101561334b57600080fd5b81019080805190602001909291905050506133ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d757374207472616e736665720000000000000000000000000000000000000081525060200191505060405180910390fd5b5050565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16613491576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b60001515600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514801561351e5750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4d757374207061737320616464726573732076616c69646174696f6e0000000081525060200191505060405180910390fd5b6003819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661370d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b60006010600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006010600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061380a81600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546152c590919063ffffffff16565b600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600f600085815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561392257600080fd5b505af1158015613936573d6000803e3d6000fd5b505050506040513d602081101561394c57600080fd5b81019080805190602001909291905050506139cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d757374207472616e736665720000000000000000000000000000000000000081525060200191505060405180910390fd5b505050565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16613a93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b60001515600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515148015613b205750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613b92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4d757374207061737320616464726573732076616c69646174696f6e0000000081525060200191505060405180910390fd5b6003819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000600580549050905090565b60096020528060005260406000206000915054906101000a900460ff1681565b60001515601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600754815260200190815260200160002060009054906101000a900460ff16151514613d91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615ab7602c913960400191505060405180910390fd5b60008090505b601760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548110156141e8576000601860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110613e2a57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050613f4b601c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600754815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460136000600754815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546152c590919063ffffffff16565b60136000600754815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000601960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905080601c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600754815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061411b8160136000600754815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461507890919063ffffffff16565b60136000600754815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506007548273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f1c6cf7f4185192b90e5dbc6c1030559d3a499bc798a5fd775870659fe4e254c4846040518082815260200191505060405180910390a450508080600101915050613d97565b506001601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600754815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600a6020528060005260406000206000915054906101000a900460ff1681565b600d6020528060005260406000206000915090505481565b60075481565b60146020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60166020528060005260406000206000915054906101000a900460ff1681565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166143a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156144325750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561446b5750600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b6144dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4d757374207061737320616464726573732076616c69646174696f6e0000000081525060200191505060405180910390fd5b600a81101580156144f057506103e88111155b614545576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615ae36026913960400191505060405180910390fd5b600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166145fa576004839080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6001600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6f1e56c55b9479aaa7ee72e01aa069c9d9e1874fa8145a0d010c1ce91483df15846040518082815260200191505060405180910390a4505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60176020528060005260406000206000915090505481565b600260005414156148a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260008190555060001515601d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146149a3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180615a906027913960400191505060405180910390fd5b600f600083815260200190815260200160002060009054906101000a900460ff16614a36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f457261206d757374206265206f70656e6564000000000000000000000000000081525060200191505060405180910390fd5b6000614a4233846114c2565b90506000811115614d74576001601d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550614b56816010600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546152c590919063ffffffff16565b6010600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550614bfc81600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546152c590919063ffffffff16565b600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015614cc657600080fd5b505af1158015614cda573d6000803e3d6000fd5b505050506040513d6020811015614cf057600080fd5b8101908080519060200190929190505050614d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d757374207472616e736665720000000000000000000000000000000000000081525060200191505060405180910390fd5b5b823373ffffffffffffffffffffffffffffffffffffffff167f0febf5fad8005f14b1cf04172c840311f6c94fe0e14e38087260ba190a357b32836040518082815260200191505060405180910390a360001515601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600754815260200190815260200160002060009054906101000a900460ff1615151415614e3957614e3833613cd5565b5b5060016000819055505050565b600f6020528060005260406000206000915054906101000a900460ff1681565b601a6020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60058181548110614ea257fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16614f90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4d7573742062652041646d696e0000000000000000000000000000000000000081525060200191505060405180910390fd5b614f9e83600754848461255f565b614fb4600160075461507890919063ffffffff16565b600781905550505050565b601d602052826000526040600020602052816000526040600020602052806000526040600020600092509250509054906101000a900460ff1681565b6000600480549050905090565b6013602052816000526040600020602052806000526040600020600091509150505481565b6018602052816000526040600020818154811061504657fe5b906000526020600020016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000808284019050838110156150f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b80601c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600754815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506152028160136000600754815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461507890919063ffffffff16565b60136000600754815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506007548273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f1c6cf7f4185192b90e5dbc6c1030559d3a499bc798a5fd775870659fe4e254c4846040518082815260200191505060405180910390a4505050565b600061530783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615909565b905092915050565b6000806000808590505b848110156155dc5760006004828154811061533057fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680156153ff5750600a60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b156155ce5761541860018561507890919063ffffffff16565b93506000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061555f606461555184600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231886040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561550857600080fd5b505afa15801561551c573d6000803e3d6000fd5b505050506040513d602081101561553257600080fd5b810190808051906020019092919050505061583990919063ffffffff16565b6158bf90919063ffffffff16565b9050615574818861507890919063ffffffff16565b965080601160008d815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505b508080600101915050615319565b5082600e60008981526020019081526020016000208190555060008590505b848110156157c05760006004828154811061561257fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680156156e15750600a60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b156157b2576156fa60018461507890919063ffffffff16565b92506000601160008b815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905061575c81878b613189565b601260008c815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b5080806001019150506155fb565b50863373ffffffffffffffffffffffffffffffffffffffff167fd7b022ad987606d8c29043f24a451ccffc5aa3a813994c086b6da216c3d8df348886868642604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a350505050505050565b60008083141561584c57600090506158b9565b600082840290508284828161585d57fe5b04146158b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615b096021913960400191505060405180910390fd5b809150505b92915050565b600061590183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506159c9565b905092915050565b60008383111582906159b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561597b578082015181840152602081019050615960565b50505050905090810190601f1680156159a85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008083118290615a75576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615a3a578082015181840152602081019050615a1f565b50505050905090810190601f168015615a675780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581615a8157fe5b04905080915050939250505056fe526577617264206173736574206d757374206e6f742068617665206265656e20636c61696d65644d757374206e6f742068617665207265676973746572656420696e20746869732065726120616c72656164794d7573742062652067726561746572207468616e20302e312c206c657373207468616e203130536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774d7573742062652063757272656e74206f722070726576696f757320657261206f6e6c79a2646970667358221220523b33e2823930670089b7bf3a73590a67a8cf64cb5932041997a6bb5b4cd22064736f6c63430006080033
Verified Source Code Full Match
Compiler: v0.6.8+commit.0bbfe453
EVM: istanbul
Optimization: No
rewards.sol 524 lines
//SPDX-License-Identifier: Unlicense
pragma solidity 0.6.8;
// ERC20 Interface
interface ERC20 {
function transfer(address, uint256) external returns (bool);
function transferFrom(
address,
address,
uint256
) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
}
contract PerlinXRewards {
using SafeMath for uint256;
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
address public PERL;
address public treasury;
address[] public arrayAdmins;
address[] public arrayPerlinPools;
address[] public arraySynths;
address[] public arrayMembers;
uint256 public currentEra;
mapping(address => bool) public isAdmin; // Tracks admin status
mapping(address => bool) public poolIsListed; // Tracks current listing status
mapping(address => bool) public poolHasMembers; // Tracks current staking status
mapping(address => bool) public poolWasListed; // Tracks if pool was ever listed
mapping(address => uint256) public mapAsset_Rewards; // Maps rewards for each asset (PERL, BAL, UNI etc)
mapping(address => uint256) public poolWeight; // Allows a reward weight to be applied; 100 = 1.0
mapping(uint256 => uint256) public mapEra_Total; // Total PERL staked in each era
mapping(uint256 => bool) public eraIsOpen; // Era is open of collecting rewards
mapping(uint256 => mapping(address => uint256)) public mapEraAsset_Reward; // Reward allocated for era
mapping(uint256 => mapping(address => uint256)) public mapEraPool_Balance; // Perls in each pool, per era
mapping(uint256 => mapping(address => uint256)) public mapEraPool_Share; // Share of reward for each pool, per era
mapping(uint256 => mapping(address => uint256)) public mapEraPool_Claims; // Total LP tokens locked for each pool, per era
mapping(address => address) public mapPool_Asset; // Uniswap pools provide liquidity to non-PERL asset
mapping(address => address) public mapSynth_EMP; // Synthetic Assets have a management contract
mapping(address => bool) public isMember; // Is Member
mapping(address => uint256) public mapMember_poolCount; // Total number of Pools member is in
mapping(address => address[]) public mapMember_arrayPools; // Array of pools for member
mapping(address => mapping(address => uint256))
public mapMemberPool_Balance; // Member's balance in pool
mapping(address => mapping(address => bool)) public mapMemberPool_Added; // Member's balance in pool
mapping(address => mapping(uint256 => bool))
public mapMemberEra_hasRegistered; // Member has registered
mapping(address => mapping(uint256 => mapping(address => uint256)))
public mapMemberEraPool_Claim; // Value of claim per pool, per era
mapping(address => mapping(uint256 => mapping(address => bool)))
public mapMemberEraAsset_hasClaimed; // Boolean claimed
// Events
event Snapshot(
address indexed admin,
uint256 indexed era,
uint256 rewardForEra,
uint256 perlTotal,
uint256 validPoolCount,
uint256 validMemberCount,
uint256 date
);
event NewPool(
address indexed admin,
address indexed pool,
address indexed asset,
uint256 assetWeight
);
event NewSynth(
address indexed pool,
address indexed synth,
address indexed expiringMultiParty
);
event MemberLocks(
address indexed member,
address indexed pool,
uint256 amount,
uint256 indexed currentEra
);
event MemberUnlocks(
address indexed member,
address indexed pool,
uint256 balance,
uint256 indexed currentEra
);
event MemberRegisters(
address indexed member,
address indexed pool,
uint256 amount,
uint256 indexed currentEra
);
event MemberClaims(address indexed member, uint256 indexed era, uint256 totalClaim);
// Only Admin can execute
modifier onlyAdmin() {
require(isAdmin[msg.sender], "Must be Admin");
_;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
constructor() public {
arrayAdmins.push(msg.sender);
isAdmin[msg.sender] = true;
PERL = 0xeca82185adCE47f39c684352B0439f030f860318;
treasury = 0x3F2a2c502E575f2fd4053c76f4E21623143518d8;
currentEra = 1;
_status = _NOT_ENTERED;
}
//==============================ADMIN================================//
// Lists a synth and its parent EMP address
function listSynth(
address pool,
address synth,
address emp,
uint256 weight
) public onlyAdmin {
require(emp != address(0), "Must pass address validation");
if (!poolWasListed[pool]) {
arraySynths.push(synth); // Add new synth
}
listPool(pool, synth, weight); // List like normal pool
mapSynth_EMP[synth] = emp; // Maps the EMP contract for look-up
emit NewSynth(pool, synth, emp);
}
// Lists a pool and its non-PERL asset (can work for Balance or Uniswap V2)
// Use "100" to be a normal weight of "1.0"
function listPool(
address pool,
address asset,
uint256 weight
) public onlyAdmin {
require(
(asset != PERL) && (asset != address(0)) && (pool != address(0)),
"Must pass address validation"
);
require(
weight >= 10 && weight <= 1000,
"Must be greater than 0.1, less than 10"
);
if (!poolWasListed[pool]) {
arrayPerlinPools.push(pool);
}
poolIsListed[pool] = true; // Tracking listing
poolWasListed[pool] = true; // Track if ever was listed
poolWeight[pool] = weight; // Note: weight of 120 = 1.2
mapPool_Asset[pool] = asset; // Map the pool to its non-perl asset
emit NewPool(msg.sender, pool, asset, weight);
}
function delistPool(address pool) public onlyAdmin {
poolIsListed[pool] = false;
}
// Quorum Action 1
function addAdmin(address newAdmin) public onlyAdmin {
require(
(isAdmin[newAdmin] == false) && (newAdmin != address(0)),
"Must pass address validation"
);
arrayAdmins.push(newAdmin);
isAdmin[newAdmin] = true;
}
function transferAdmin(address newAdmin) public onlyAdmin {
require(
(isAdmin[newAdmin] == false) && (newAdmin != address(0)),
"Must pass address validation"
);
arrayAdmins.push(newAdmin);
isAdmin[msg.sender] = false;
isAdmin[newAdmin] = true;
}
// Snapshot a new Era, allocating any new rewards found on the address, increment Era
// Admin should send reward funds first
function snapshot(address rewardAsset) public onlyAdmin {
snapshotInEra(rewardAsset, currentEra); // Snapshots PERL balances
currentEra = currentEra.add(1); // Increment the eraCount, so users can't register in a previous era.
}
// Snapshot a particular rewwardAsset, but don't increment Era (like Balancer Rewards)
// Do this after snapshotPools()
function snapshotInEra(address rewardAsset, uint256 era) public onlyAdmin {
uint256 start = 0;
uint256 end = poolCount();
snapshotInEraWithOffset(rewardAsset, era, start, end);
}
// Snapshot with offset (in case runs out of gas)
function snapshotWithOffset(
address rewardAsset,
uint256 start,
uint256 end
) public onlyAdmin {
snapshotInEraWithOffset(rewardAsset, currentEra, start, end); // Snapshots PERL balances
currentEra = currentEra.add(1); // Increment the eraCount, so users can't register in a previous era.
}
// Snapshot a particular rewwardAsset, with offset
function snapshotInEraWithOffset(
address rewardAsset,
uint256 era,
uint256 start,
uint256 end
) public onlyAdmin {
require(rewardAsset != address(0), "Address must not be 0x0");
require(
(era >= currentEra - 1) && (era <= currentEra),
"Must be current or previous era only"
);
uint256 amount = ERC20(rewardAsset).balanceOf(address(this)).sub(
mapAsset_Rewards[rewardAsset]
);
require(amount > 0, "Amount must be non-zero");
mapAsset_Rewards[rewardAsset] = mapAsset_Rewards[rewardAsset].add(
amount
);
mapEraAsset_Reward[era][rewardAsset] = mapEraAsset_Reward[era][rewardAsset]
.add(amount);
eraIsOpen[era] = true;
updateRewards(era, amount, start, end); // Snapshots PERL balances
}
// Note, due to EVM gas limits, poolCount should be less than 100 to do this before running out of gas
function updateRewards(
uint256 era,
uint256 rewardForEra,
uint256 start,
uint256 end
) internal {
// First snapshot balances of each pool
uint256 perlTotal;
uint256 validPoolCount;
uint256 validMemberCount;
for (uint256 i = start; i < end; i++) {
address pool = arrayPerlinPools[i];
if (poolIsListed[pool] && poolHasMembers[pool]) {
validPoolCount = validPoolCount.add(1);
uint256 weight = poolWeight[pool];
uint256 weightedBalance = (
ERC20(PERL).balanceOf(pool).mul(weight)).div(100); // (depth * weight) / 100
perlTotal = perlTotal.add(weightedBalance);
mapEraPool_Balance[era][pool] = weightedBalance;
}
}
mapEra_Total[era] = perlTotal;
// Then snapshot share of the reward for the era
for (uint256 i = start; i < end; i++) {
address pool = arrayPerlinPools[i];
if (poolIsListed[pool] && poolHasMembers[pool]) {
validMemberCount = validMemberCount.add(1);
uint256 part = mapEraPool_Balance[era][pool];
mapEraPool_Share[era][pool] = getShare(
part,
perlTotal,
rewardForEra
);
}
}
emit Snapshot(
msg.sender,
era,
rewardForEra,
perlTotal,
validPoolCount,
validMemberCount,
now
);
}
// Quorum Action
// Remove unclaimed rewards and disable era for claiming
function removeReward(uint256 era, address rewardAsset) public onlyAdmin {
uint256 amount = mapEraAsset_Reward[era][rewardAsset];
mapEraAsset_Reward[era][rewardAsset] = 0;
mapAsset_Rewards[rewardAsset] = mapAsset_Rewards[rewardAsset].sub(
amount
);
eraIsOpen[era] = false;
require(
ERC20(rewardAsset).transfer(treasury, amount),
"Must transfer"
);
}
// Quorum Action - Reuses adminApproveEraAsset() logic since unlikely to collide
// Use in anger to sweep off assets (such as accidental airdropped tokens)
function sweep(address asset, uint256 amount) public onlyAdmin {
require(
ERC20(asset).transfer(treasury, amount),
"Must transfer"
);
}
//============================== USER - LOCK/UNLOCK ================================//
// Member locks some LP tokens
function lock(address pool, uint256 amount) public nonReentrant {
require(poolIsListed[pool] == true, "Must be listed");
if (!isMember[msg.sender]) {
// Add new member
arrayMembers.push(msg.sender);
isMember[msg.sender] = true;
}
if (!poolHasMembers[pool]) {
// Records existence of member
poolHasMembers[pool] = true;
}
if (!mapMemberPool_Added[msg.sender][pool]) {
// Record all the pools member is in
mapMember_poolCount[msg.sender] = mapMember_poolCount[msg.sender]
.add(1);
mapMember_arrayPools[msg.sender].push(pool);
mapMemberPool_Added[msg.sender][pool] = true;
}
require(
ERC20(pool).transferFrom(msg.sender, address(this), amount),
"Must transfer"
); // Uni/Bal LP tokens return bool
mapMemberPool_Balance[msg.sender][pool] = mapMemberPool_Balance[msg.sender][pool]
.add(amount); // Record total pool balance for member
registerClaim(msg.sender, pool, amount); // Register claim
emit MemberLocks(msg.sender, pool, amount, currentEra);
}
// Member unlocks all from a pool
function unlock(address pool) public nonReentrant {
uint256 balance = mapMemberPool_Balance[msg.sender][pool];
require(balance > 0, "Must have a balance to claim");
mapMemberPool_Balance[msg.sender][pool] = 0; // Zero out balance
require(ERC20(pool).transfer(msg.sender, balance), "Must transfer"); // Then transfer
if (ERC20(pool).balanceOf(address(this)) == 0) {
poolHasMembers[pool] = false; // If nobody is staking any more
}
emit MemberUnlocks(msg.sender, pool, balance, currentEra);
}
//============================== USER - CLAIM================================//
// Member registers claim in a single pool
function registerClaim(
address member,
address pool,
uint256 amount
) internal {
mapMemberEraPool_Claim[member][currentEra][pool] += amount;
mapEraPool_Claims[currentEra][pool] = mapEraPool_Claims[currentEra][pool]
.add(amount);
emit MemberRegisters(member, pool, amount, currentEra);
}
// Member registers claim in all pools
function registerAllClaims(address member) public {
require(
mapMemberEra_hasRegistered[msg.sender][currentEra] == false,
"Must not have registered in this era already"
);
for (uint256 i = 0; i < mapMember_poolCount[member]; i++) {
address pool = mapMember_arrayPools[member][i];
// first deduct any previous claim
mapEraPool_Claims[currentEra][pool] = mapEraPool_Claims[currentEra][pool]
.sub(mapMemberEraPool_Claim[member][currentEra][pool]);
uint256 amount = mapMemberPool_Balance[member][pool]; // then get latest balance
mapMemberEraPool_Claim[member][currentEra][pool] = amount; // then update the claim
mapEraPool_Claims[currentEra][pool] = mapEraPool_Claims[currentEra][pool]
.add(amount); // then add to total
emit MemberRegisters(member, pool, amount, currentEra);
}
mapMemberEra_hasRegistered[msg.sender][currentEra] = true;
}
// Member claims in a era
function claim(uint256 era, address rewardAsset)
public
nonReentrant
{
require(
mapMemberEraAsset_hasClaimed[msg.sender][era][rewardAsset] == false,
"Reward asset must not have been claimed"
);
require(eraIsOpen[era], "Era must be opened");
uint256 totalClaim = checkClaim(msg.sender, era);
if (totalClaim > 0) {
mapMemberEraAsset_hasClaimed[msg.sender][era][rewardAsset] = true; // Register claim
mapEraAsset_Reward[era][rewardAsset] = mapEraAsset_Reward[era][rewardAsset]
.sub(totalClaim); // Decrease rewards for that era
mapAsset_Rewards[rewardAsset] = mapAsset_Rewards[rewardAsset].sub(
totalClaim
); // Decrease rewards in total
require(
ERC20(rewardAsset).transfer(msg.sender, totalClaim),
"Must transfer"
); // Then transfer
}
emit MemberClaims(msg.sender, era, totalClaim);
if (mapMemberEra_hasRegistered[msg.sender][currentEra] == false) {
registerAllClaims(msg.sender); // Register another claim
}
}
// Member checks claims in all pools
function checkClaim(address member, uint256 era)
public
view
returns (uint256 totalClaim)
{
for (uint256 i = 0; i < mapMember_poolCount[member]; i++) {
address pool = mapMember_arrayPools[member][i];
totalClaim += checkClaimInPool(member, era, pool);
}
return totalClaim;
}
// Member checks claim in a single pool
function checkClaimInPool(
address member,
uint256 era,
address pool
) public view returns (uint256 claimShare) {
uint256 poolShare = mapEraPool_Share[era][pool]; // Requires admin snapshotting for era first, else 0
uint256 memberClaimInEra = mapMemberEraPool_Claim[member][era][pool]; // Requires member registering claim in the era
uint256 totalClaimsInEra = mapEraPool_Claims[era][pool]; // Sum of all claims in a era
if (totalClaimsInEra > 0) {
// Requires non-zero balance of the pool tokens
claimShare = getShare(
memberClaimInEra,
totalClaimsInEra,
poolShare
);
} else {
claimShare = 0;
}
return claimShare;
}
//==============================UTILS================================//
// Get the share of a total
function getShare(
uint256 part,
uint256 total,
uint256 amount
) public pure returns (uint256 share) {
return (amount.mul(part)).div(total);
}
function adminCount() public view returns (uint256) {
return arrayAdmins.length;
}
function poolCount() public view returns (uint256) {
return arrayPerlinPools.length;
}
function synthCount() public view returns (uint256) {
return arraySynths.length;
}
function memberCount() public view returns (uint256) {
return arrayMembers.length;
}
}
Read Contract
PERL 0xc251adeb → address
adminCount 0x2b7832b3 → uint256
arrayAdmins 0x4445c1ea → address
arrayMembers 0x436f80be → address
arrayPerlinPools 0x32bc68be → address
arraySynths 0xeb765955 → address
checkClaim 0x0382ad26 → uint256
checkClaimInPool 0x3e66034f → uint256
currentEra 0x973628f6 → uint256
eraIsOpen 0xe07dbfbd → bool
getShare 0x69b30398 → uint256
isAdmin 0x24d7806c → bool
isMember 0xa230c524 → bool
mapAsset_Rewards 0x522cff25 → uint256
mapEraAsset_Reward 0x44d3d337 → uint256
mapEraPool_Balance 0x4dd85b5e → uint256
mapEraPool_Claims 0xf96e9ea1 → uint256
mapEraPool_Share 0x322e2604 → uint256
mapEra_Total 0x26b80529 → uint256
mapMemberEraAsset_hasClaimed 0xed06d4e2 → bool
mapMemberEraPool_Claim 0x44d7e455 → uint256
mapMemberEra_hasRegistered 0x31405c03 → bool
mapMemberPool_Added 0xe4ebdfa5 → bool
mapMemberPool_Balance 0x3d23e24a → uint256
mapMember_arrayPools 0xfa8f382a → address
mapMember_poolCount 0xce110e4b → uint256
mapPool_Asset 0xa19d1646 → address
mapSynth_EMP 0x5976c67c → address
memberCount 0x11aee380 → uint256
poolCount 0xf525cb68 → uint256
poolHasMembers 0x87e2662e → bool
poolIsListed 0x7f2277b4 → bool
poolWasListed 0x16d53471 → bool
poolWeight 0x8b5e608b → uint256
synthCount 0x78a45a24 → uint256
treasury 0x61d027b3 → address
Write Contract 15 functions
These functions modify contract state and require a wallet transaction to execute.
addAdmin 0x70480275
address newAdmin
claim 0xddd5e1b2
uint256 era
address rewardAsset
delistPool 0x306faf4a
address pool
listPool 0xbaff15ce
address pool
address asset
uint256 weight
listSynth 0x429d7e8f
address pool
address synth
address emp
uint256 weight
lock 0x282d3fdf
address pool
uint256 amount
registerAllClaims 0x845696b4
address member
removeReward 0x71586b1f
uint256 era
address rewardAsset
snapshot 0x26512160
address rewardAsset
snapshotInEra 0x4a5cab98
address rewardAsset
uint256 era
snapshotInEraWithOffset 0x3224e2f2
address rewardAsset
uint256 era
uint256 start
uint256 end
snapshotWithOffset 0xec7d7199
address rewardAsset
uint256 start
uint256 end
sweep 0x6ea056a9
address asset
uint256 amount
transferAdmin 0x75829def
address newAdmin
unlock 0x2f6c493c
address pool
Recent Transactions
This address has 1 on-chain transactions, but only 1.1% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →