Contract Address Details

0x11e46DB40d4438D1c64f68993CA43b03Ac1B6A6B

dgPointer Last Balance Update: Block #11343408
Created by 0x1fcd–2c0f8a at 0xce14–52c0ce

Balance

0 MATIC

(@ /MATIC)

Fetching tokens...

Contract name:
dgPointer




Optimization enabled
true
Compiler version
v0.7.4+commit.3f05b770




Optimization runs
200
EVM Version
default

Constructor Arguments

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000034e455700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003352e300000000000000000000000000000000000000000000000000000000000

Arg [0] (address) : 0x0000000000000000000000000000000000000000
Arg [1] (string) : NEW
Arg [2] (string) : 5.0

              

Contract source code

/**
* Submitted for verification at blockscout.com on 2020-11-07 19:31:05.347367Z
*/
// SPDX-License-Identifier: -- 🎲 --
pragma solidity ^0.7.4;
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) {
require(b <= a, 'SafeMath: subtraction overflow');
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) {
require(b > 0, 'SafeMath: division by zero');
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, 'SafeMath: modulo by zero');
return a % b;
}
}
contract AccessController {
address public ceoAddress;
address public workerAddress;
bool public paused = false;
// mapping (address => enumRoles) accessRoles; // multiple operators idea
event CEOSet(address newCEO);
event WorkerSet(address newWorker);
event Paused();
event Unpaused();
constructor() {
ceoAddress = msg.sender;
workerAddress = msg.sender;
emit CEOSet(ceoAddress);
emit WorkerSet(workerAddress);
}
modifier onlyCEO() {
require(
msg.sender == ceoAddress,
'AccessControl: CEO access denied'
);
_;
}
modifier onlyWorker() {
require(
msg.sender == workerAddress,
'AccessControl: worker access denied'
);
_;
}
modifier whenNotPaused() {
require(
!paused,
'AccessControl: currently paused'
);
_;
}
modifier whenPaused {
require(
paused,
'AccessControl: currenlty not paused'
);
_;
}
function setCEO(address _newCEO) public onlyCEO {
require(
_newCEO != address(0x0),
'AccessControl: invalid CEO address'
);
ceoAddress = _newCEO;
emit CEOSet(ceoAddress);
}
function setWorker(address _newWorker) external {
require(
_newWorker != address(0x0),
'AccessControl: invalid worker address'
);
require(
msg.sender == ceoAddress || msg.sender == workerAddress,
'AccessControl: invalid worker address'
);
workerAddress = _newWorker;
emit WorkerSet(workerAddress);
}
function pause() external onlyWorker whenNotPaused {
paused = true;
emit Paused();
}
function unpause() external onlyCEO whenPaused {
paused = false;
emit Unpaused();
}
}
interface ERC20Token {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(
address indexed from,
address indexed to,
uint256 value
);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
contract EIP712Base {
struct EIP712Domain {
string name;
string version;
uint256 chainId;
address verifyingContract;
}
bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"));
bytes32 internal domainSeperator;
constructor(string memory name, string memory version) {
domainSeperator = keccak256(abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(bytes(name)),
keccak256(bytes(version)),
getChainID(),
address(this)
));
}
function getChainID() internal pure returns (uint256 id) {
assembly {
id := 1 // set to Goerli for now, Mainnet later
}
}
function getDomainSeperator() private view returns(bytes32) {
return domainSeperator;
}
/**
* Accept message hash and returns hash message in EIP712 compatible form
* So that it can be used to recover signer from signature signed using EIP712 formatted data
* https://eips.ethereum.org/EIPS/eip-712
* "\\x19" makes the encoding deterministic
* "\\x01" is the version byte to make it compatible to EIP-191
*/
function toTypedMessageHash(bytes32 messageHash) internal view returns(bytes32) {
return keccak256(abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash));
}
}
abstract contract EIP712MetaTransaction is EIP712Base {
using SafeMath for uint256;
bytes32 private constant META_TRANSACTION_TYPEHASH =
keccak256(
bytes(
"MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
)
);
event MetaTransactionExecuted(
address userAddress,
address payable relayerAddress,
bytes functionSignature
);
mapping(address => uint256) internal nonces;
/*
* Meta transaction structure.
* No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
* He should call the desired function directly in that case.
*/
struct MetaTransaction {
uint256 nonce;
address from;
bytes functionSignature;
}
function executeMetaTransaction(
address userAddress,
bytes memory functionSignature,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
)
public
payable
returns(bytes memory)
{
MetaTransaction memory metaTx = MetaTransaction(
{
nonce: nonces[userAddress],
from: userAddress,
functionSignature: functionSignature
}
);
require(
verify(
userAddress,
metaTx,
sigR,
sigS,
sigV
), "Signer and signature do not match"
);
nonces[userAddress] =
nonces[userAddress].add(1);
// Append userAddress at the end to extract it from calling context
(bool success, bytes memory returnData) = address(this).call(
abi.encodePacked(
functionSignature,
userAddress
)
);
require(
success,
'Function call not successful'
);
emit MetaTransactionExecuted(
userAddress,
msg.sender,
functionSignature
);
return returnData;
}
function hashMetaTransaction(
MetaTransaction memory metaTx
)
internal
pure
returns (bytes32)
{
return keccak256(
abi.encode(
META_TRANSACTION_TYPEHASH,
metaTx.nonce,
metaTx.from,
keccak256(metaTx.functionSignature)
)
);
}
function getNonce(
address user
)
external
view
returns(uint256 nonce)
{
nonce = nonces[user];
}
function verify(
address user,
MetaTransaction memory metaTx,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
)
internal
view
returns (bool)
{
address signer = ecrecover(
toTypedMessageHash(
hashMetaTransaction(metaTx)
),
sigV,
sigR,
sigS
);
require(
signer != address(0x0),
'Invalid signature'
);
return signer == user;
}
function msgSender() internal view returns(address sender) {
if(msg.sender == address(this)) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
}
contract dgPointer is AccessController, EIP712MetaTransaction {
using SafeMath for uint256;
uint256 public defaultPlayerBonus = 30;
uint256 public defaultWearableBonus = 40;
bool public collectingEnabled;
bool public distributionEnabled;
ERC20Token public distributionToken;
mapping(address => bool) public declaredContracts;
mapping(address => uint256) public pointsBalancer;
mapping(address => mapping(address => uint256)) public tokenToPointRatio;
mapping(uint256 => uint256) public playerBonuses;
mapping(uint256 => uint256) public wearableBonuses;
mapping(address => address) public affiliateData;
uint256 public affiliateBonus;
uint256 public wearableBonusPerObject;
event updatedPlayerBonus(
uint256 playersCount,
uint256 newBonus
);
event updatedAffiliateBonus(
uint256 newBonus
);
event updatedMaxPlayerBonus(
uint256 newBonus
);
constructor(
address _distributionToken,
string memory name,
string memory version
) EIP712Base(name, version) {
distributionToken = ERC20Token(
_distributionToken
);
affiliateBonus = 10;
playerBonuses[2] = 10;
playerBonuses[3] = 20;
playerBonuses[4] = 30;
wearableBonuses[1] = 10;
wearableBonuses[2] = 20;
wearableBonuses[3] = 30;
wearableBonuses[4] = 40;
}
function assignAffiliate(
address _affiliate,
address _player
)
external
onlyWorker
{
require(
affiliateData[_player] == address(0x0),
'Pointer: player already affiliated'
);
affiliateData[_player] = _affiliate;
}
function addPoints(
address _player,
uint256 _points,
address _token
)
external
returns (
uint256 newPoints,
uint256 multiplierA,
uint256 multiplierB
)
{
return addPoints(
_player,
_points,
_token,
1,
0
);
}
function addPoints(
address _player,
uint256 _points,
address _token,
uint256 _playersCount
)
public
returns (
uint256 newPoints,
uint256 multiplier,
uint256 multiplierB
)
{
return addPoints(
_player,
_points,
_token,
_playersCount,
0
);
}
function addPoints(
address _player,
uint256 _points,
address _token,
uint256 _playersCount,
uint256 _wearablesCount
)
public
returns (
uint256 newPoints,
uint256 multiplierA,
uint256 multiplierB
)
{
require(
_playersCount > 0,
'dgPointer: _playersCount error'
);
if (_isDeclaredContract(msg.sender) && collectingEnabled) {
multiplierA = getPlayerMultiplier(
_playersCount,
playerBonuses[_playersCount],
defaultPlayerBonus
);
multiplierB = getWearableMultiplier(
_wearablesCount,
wearableBonuses[_wearablesCount],
defaultWearableBonus
);
newPoints = _points
.div(tokenToPointRatio[msg.sender][_token])
.mul(uint256(100)
.add(multiplierA)
.add(multiplierB)
)
.div(100);
pointsBalancer[_player] =
pointsBalancer[_player].add(newPoints);
_applyAffiliatePoints(
_player,
newPoints
);
}
}
function _applyAffiliatePoints(
address _player,
uint256 _points
)
internal
{
if (_isAffiliated(_player)) {
pointsBalancer[affiliateData[_player]] =
pointsBalancer[affiliateData[_player]] + _points
.mul(affiliateBonus)
.div(100);
}
}
function getPlayerMultiplier(
uint256 _playerCount,
uint256 _playerBonus,
uint256 _defaultPlayerBonus
)
internal
pure
returns (uint256)
{
if (_playerCount == 1) return 0;
return _playerCount > 0 && _playerBonus == 0
? _defaultPlayerBonus
: _playerBonus;
}
function getWearableMultiplier(
uint256 _wearableCount,
uint256 _wearableBonus,
uint256 _defaultWearableBonus
)
internal
pure
returns (uint256)
{
return _wearableCount > 0 && _wearableBonus == 0
? _defaultWearableBonus
: _wearableBonus;
}
function _isAffiliated(
address _player
)
internal
view
returns (bool)
{
return affiliateData[_player] != address(0x0);
}
function getMyTokens()
external
returns(uint256 tokenAmount)
{
return distributeTokens(msgSender());
}
function distributeTokensBulk(
address[] memory _player
)
external
{
for(uint i = 0; i < _player.length; i++) {
distributeTokens(_player[i]);
}
}
function distributeTokens(
address _player
)
public
returns (uint256 tokenAmount)
{
require(
distributionEnabled == true,
'Pointer: distribution disabled'
);
tokenAmount = pointsBalancer[_player];
pointsBalancer[_player] = 0;
distributionToken.transfer(_player, tokenAmount);
}
function changePlayerBonus(uint256 _bonusIndex, uint256 _newBonus)
external
onlyCEO
{
playerBonuses[_bonusIndex] = _newBonus;
emit updatedPlayerBonus(
_bonusIndex,
playerBonuses[_bonusIndex]
);
}
function changeAffiliateBonus(uint256 _newAffiliateBonus)
external
onlyCEO
{
affiliateBonus = _newAffiliateBonus;
emit updatedAffiliateBonus(
_newAffiliateBonus
);
}
function changeDefaultPlayerBonus(
uint256 _newDefaultPlayerBonus
)
external
onlyCEO
{
defaultPlayerBonus =_newDefaultPlayerBonus;
emit updatedMaxPlayerBonus(
defaultPlayerBonus
);
}
function changeMaxWearableBonus(
uint256 _newMaxWearableBonus
)
external
onlyCEO
{
defaultWearableBonus = _newMaxWearableBonus;
}
function changeDistributionToken(
address _newDistributionToken
)
external
onlyCEO
{
distributionToken = ERC20Token(
_newDistributionToken
);
}
function setTokenToPointRatio(
address _gameAddress,
address _token,
uint256 _ratio
)
external
onlyCEO
{
tokenToPointRatio[_gameAddress][_token] = _ratio;
}
function enableCollecting(
bool _state
)
external
onlyCEO
{
collectingEnabled = _state;
}
function enableDistribtion(
bool _state
)
external
onlyCEO
{
distributionEnabled = _state;
}
function declareContract(
address _contract
)
external
onlyCEO
{
declaredContracts[_contract] = true;
}
function unDeclareContract(
address _contract
)
external
onlyCEO
{
declaredContracts[_contract] = false;
}
function _isDeclaredContract(
address _contract
)
internal
view
returns (bool)
{
return declaredContracts[_contract];
}
}

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_distributionToken","internalType":"address"},{"type":"string","name":"name","internalType":"string"},{"type":"string","name":"version","internalType":"string"}]},{"type":"event","name":"CEOSet","inputs":[{"type":"address","name":"newCEO","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"MetaTransactionExecuted","inputs":[{"type":"address","name":"userAddress","internalType":"address","indexed":false},{"type":"address","name":"relayerAddress","internalType":"address payable","indexed":false},{"type":"bytes","name":"functionSignature","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"Paused","inputs":[],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[],"anonymous":false},{"type":"event","name":"WorkerSet","inputs":[{"type":"address","name":"newWorker","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"updatedAffiliateBonus","inputs":[{"type":"uint256","name":"newBonus","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"updatedMaxPlayerBonus","inputs":[{"type":"uint256","name":"newBonus","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"updatedPlayerBonus","inputs":[{"type":"uint256","name":"playersCount","internalType":"uint256","indexed":false},{"type":"uint256","name":"newBonus","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"newPoints","internalType":"uint256"},{"type":"uint256","name":"multiplierA","internalType":"uint256"},{"type":"uint256","name":"multiplierB","internalType":"uint256"}],"name":"addPoints","inputs":[{"type":"address","name":"_player","internalType":"address"},{"type":"uint256","name":"_points","internalType":"uint256"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_playersCount","internalType":"uint256"},{"type":"uint256","name":"_wearablesCount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"newPoints","internalType":"uint256"},{"type":"uint256","name":"multiplierA","internalType":"uint256"},{"type":"uint256","name":"multiplierB","internalType":"uint256"}],"name":"addPoints","inputs":[{"type":"address","name":"_player","internalType":"address"},{"type":"uint256","name":"_points","internalType":"uint256"},{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"newPoints","internalType":"uint256"},{"type":"uint256","name":"multiplier","internalType":"uint256"},{"type":"uint256","name":"multiplierB","internalType":"uint256"}],"name":"addPoints","inputs":[{"type":"address","name":"_player","internalType":"address"},{"type":"uint256","name":"_points","internalType":"uint256"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_playersCount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"affiliateBonus","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"affiliateData","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"assignAffiliate","inputs":[{"type":"address","name":"_affiliate","internalType":"address"},{"type":"address","name":"_player","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"ceoAddress","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeAffiliateBonus","inputs":[{"type":"uint256","name":"_newAffiliateBonus","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeDefaultPlayerBonus","inputs":[{"type":"uint256","name":"_newDefaultPlayerBonus","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeDistributionToken","inputs":[{"type":"address","name":"_newDistributionToken","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeMaxWearableBonus","inputs":[{"type":"uint256","name":"_newMaxWearableBonus","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changePlayerBonus","inputs":[{"type":"uint256","name":"_bonusIndex","internalType":"uint256"},{"type":"uint256","name":"_newBonus","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"collectingEnabled","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"declareContract","inputs":[{"type":"address","name":"_contract","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"declaredContracts","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"defaultPlayerBonus","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"defaultWearableBonus","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"tokenAmount","internalType":"uint256"}],"name":"distributeTokens","inputs":[{"type":"address","name":"_player","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"distributeTokensBulk","inputs":[{"type":"address[]","name":"_player","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"distributionEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ERC20Token"}],"name":"distributionToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableCollecting","inputs":[{"type":"bool","name":"_state","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableDistribtion","inputs":[{"type":"bool","name":"_state","internalType":"bool"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"executeMetaTransaction","inputs":[{"type":"address","name":"userAddress","internalType":"address"},{"type":"bytes","name":"functionSignature","internalType":"bytes"},{"type":"bytes32","name":"sigR","internalType":"bytes32"},{"type":"bytes32","name":"sigS","internalType":"bytes32"},{"type":"uint8","name":"sigV","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"tokenAmount","internalType":"uint256"}],"name":"getMyTokens","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"nonce","internalType":"uint256"}],"name":"getNonce","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"playerBonuses","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pointsBalancer","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCEO","inputs":[{"type":"address","name":"_newCEO","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTokenToPointRatio","inputs":[{"type":"address","name":"_gameAddress","internalType":"address"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_ratio","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setWorker","inputs":[{"type":"address","name":"_newWorker","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tokenToPointRatio","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unDeclareContract","inputs":[{"type":"address","name":"_contract","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"wearableBonusPerObject","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"wearableBonuses","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"workerAddress","inputs":[]}]
            

Contract Byte Code

0x6080604052600436106102305760003560e01c80638456cb591161012e578063c568e188116100ab578063e726c3d71161006f578063e726c3d7146109b7578063e9f259df146109f2578063f3b7561314610a07578063f6547b7f14610a31578063f66851e214610a4657610230565b8063c568e18814610904578063cbd88f4814610930578063d2c60a0d14610945578063dd3e79d914610978578063e53a0860146109a257610230565b8063b1d17c98116100f2578063b1d17c98146107a6578063b4bdeec8146107d9578063bd8918281461080c578063c0ff11c214610821578063c26f6d44146108d157610230565b80638456cb591461070157806386608326146107165780638ceb38de1461072b5780639ab24e421461075e5780639d1390621461079157610230565b80633787f89f116101bc5780634fe8681f116101805780634fe8681f1461060d57806350216272146106505780635b3b136a1461067c5780635c975abb146106915780637d233970146106ba57610230565b80633787f89f1461052857806339c2a538146105585780633be254ad1461058b5780633f4ba83a146105ce5780634d266dd7146105e357610230565b80631c2af4df116102035780631c2af4df1461043157806327d7874c1461045d5780632d0335ab14610490578063324a6d5b146104c3578063360e8ead146104fe57610230565b806306804295146102355780630a0f8168146102a05780630bacdb18146102d15780630c53c51c146102f8575b600080fd5b34801561024157600080fd5b50610282600480360360a081101561025857600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135610a79565b60408051938452602084019290925282820152519081900360600190f35b3480156102ac57600080fd5b506102b5610bda565b604080516001600160a01b039092168252519081900360200190f35b3480156102dd57600080fd5b506102e6610be9565b60408051918252519081900360200190f35b6103bc600480360360a081101561030e57600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561033957600080fd5b82018360208201111561034b57600080fd5b8035906020019184600183028401116401000000008311171561036d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550508235935050506020810135906040013560ff16610bef565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103f65781810151838201526020016103de565b50505050905090810190601f1680156104235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561043d57600080fd5b5061045b6004803603602081101561045457600080fd5b5035610efc565b005b34801561046957600080fd5b5061045b6004803603602081101561048057600080fd5b50356001600160a01b0316610f84565b34801561049c57600080fd5b506102e6600480360360208110156104b357600080fd5b50356001600160a01b0316611070565b3480156104cf57600080fd5b5061045b600480360360408110156104e657600080fd5b506001600160a01b038135811691602001351661108b565b34801561050a57600080fd5b506102e66004803603602081101561052157600080fd5b503561115b565b34801561053457600080fd5b5061045b6004803603604081101561054b57600080fd5b508035906020013561116d565b34801561056457600080fd5b506102e66004803603602081101561057b57600080fd5b50356001600160a01b031661120b565b34801561059757600080fd5b50610282600480360360608110156105ae57600080fd5b506001600160a01b0381358116916020810135916040909101351661121d565b3480156105da57600080fd5b5061045b611240565b3480156105ef57600080fd5b5061045b6004803603602081101561060657600080fd5b503561130d565b34801561061957600080fd5b5061045b6004803603606081101561063057600080fd5b506001600160a01b0381358116916020810135909116906040013561135f565b34801561065c57600080fd5b5061045b6004803603602081101561067357600080fd5b503515156113d8565b34801561068857600080fd5b506102e6611438565b34801561069d57600080fd5b506106a6611450565b604080519115158252519081900360200190f35b3480156106c657600080fd5b50610282600480360360808110156106dd57600080fd5b506001600160a01b0381358116916020810135916040820135169060600135611460565b34801561070d57600080fd5b5061045b611483565b34801561072257600080fd5b506106a6611569565b34801561073757600080fd5b506106a66004803603602081101561074e57600080fd5b50356001600160a01b0316611577565b34801561076a57600080fd5b5061045b6004803603602081101561078157600080fd5b50356001600160a01b031661158c565b34801561079d57600080fd5b506102b56115fa565b3480156107b257600080fd5b506102e6600480360360208110156107c957600080fd5b50356001600160a01b031661160f565b3480156107e557600080fd5b5061045b600480360360208110156107fc57600080fd5b50356001600160a01b031661171a565b34801561081857600080fd5b506106a661178b565b34801561082d57600080fd5b5061045b6004803603602081101561084457600080fd5b81019060208101813564010000000081111561085f57600080fd5b82018360208201111561087157600080fd5b8035906020019184602083028401116401000000008311171561089357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611794945050505050565b3480156108dd57600080fd5b5061045b600480360360208110156108f457600080fd5b50356001600160a01b03166117c9565b34801561091057600080fd5b5061045b6004803603602081101561092757600080fd5b503515156118c6565b34801561093c57600080fd5b506102b561192d565b34801561095157600080fd5b506102b56004803603602081101561096857600080fd5b50356001600160a01b031661193c565b34801561098457600080fd5b506102e66004803603602081101561099b57600080fd5b5035611957565b3480156109ae57600080fd5b506102e6611969565b3480156109c357600080fd5b506102e6600480360360408110156109da57600080fd5b506001600160a01b038135811691602001351661196f565b3480156109fe57600080fd5b506102e661198c565b348015610a1357600080fd5b5061045b60048036036020811015610a2a57600080fd5b5035611992565b348015610a3d57600080fd5b506102e6611a1a565b348015610a5257600080fd5b5061045b60048036036020811015610a6957600080fd5b50356001600160a01b0316611a20565b6000806000808511610ad2576040805162461bcd60e51b815260206004820152601e60248201527f6467506f696e7465723a205f706c6179657273436f756e74206572726f720000604482015290519081900360640190fd5b610adb33611a97565b8015610ae9575060065460ff165b15610bcf576000858152600a6020526040902054600454610b0b918791611ab5565b9150610b2d84600b600087815260200190815260200160002054600554611aec565b9050610b866064610b80610b4b84610b458488611b04565b90611b04565b3360009081526009602090815260408083206001600160a01b038e168452909152902054610b7a908c90611b67565b90611bd1565b90611b67565b6001600160a01b038916600090815260086020526040902054909350610bac9084611b04565b6001600160a01b038916600090815260086020526040902055610bcf8884611c2a565b955095509592505050565b6000546001600160a01b031681565b60045481565b6060610bf9611ec3565b50604080516060810182526001600160a01b03881660008181526003602090815290849020548352820152908101869052610c378782878787611c87565b610c725760405162461bcd60e51b8152600401808060200182810382526021815260200180611fdc6021913960400191505060405180910390fd5b6001600160a01b038716600090815260036020526040902054610c96906001611b04565b60036000896001600160a01b03166001600160a01b031681526020019081526020016000208190555060006060306001600160a01b0316888a6040516020018083805190602001908083835b60208310610d015780518252601f199092019160209182019101610ce2565b6001836020036101000a038019825116818451168082178552505050505050905001826001600160a01b031660601b8152601401925050506040516020818303038152906040526040518082805190602001908083835b60208310610d775780518252601f199092019160209182019101610d58565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610dd9576040519150601f19603f3d011682016040523d82523d6000602084013e610dde565b606091505b509150915081610e35576040805162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604482015290519081900360640190fd5b7f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b89338a60405180846001600160a01b03168152602001836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610eb4578181015183820152602001610e9c565b50505050905090810190601f168015610ee15780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a198975050505050505050565b6000546001600160a01b03163314610f49576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b600d8190556040805182815290517fd73ca31205f4543b5bd74800f4fa1722d3fc5977c9edae0065e5fdf6be23a55b9181900360200190a150565b6000546001600160a01b03163314610fd1576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b6001600160a01b0381166110165760405162461bcd60e51b8152600401808060200182810382526022815260200180611f766022913960400191505060405180910390fd5b600080546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517ff97cbb4246b709036319093e5ff31674b9f6759076d153e1bea1f60392170fc0916020908290030190a150565b6001600160a01b031660009081526003602052604090205490565b6001546001600160a01b031633146110d45760405162461bcd60e51b8152600401808060200182810382526023815260200180611f986023913960400191505060405180910390fd5b6001600160a01b038181166000908152600c6020526040902054161561112b5760405162461bcd60e51b81526004018080602001828103825260228152602001806120206022913960400191505060405180910390fd5b6001600160a01b039081166000908152600c602052604090208054919092166001600160a01b0319909116179055565b600b6020526000908152604090205481565b6000546001600160a01b031633146111ba576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b6000828152600a6020908152604091829020839055815184815290810183905281517fa2132181d06a2c9e6fad1f38530f0da936441ea9cb54eb4ea02dd303fc4f14a3929181900390910190a15050565b60086020526000908152604090205481565b600080600061123186868660016000610a79565b92509250925093509350939050565b6000546001600160a01b0316331461128d576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b600154600160a01b900460ff166112d55760405162461bcd60e51b8152600401808060200182810382526023815260200180611ffd6023913960400191505060405180910390fd5b6001805460ff60a01b191690556040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b6000546001600160a01b0316331461135a576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b600555565b6000546001600160a01b031633146113ac576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b6001600160a01b0392831660009081526009602090815260408083209490951682529290925291902055565b6000546001600160a01b03163314611425576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b6006805460ff1916911515919091179055565b600061144a611445611d71565b61160f565b90505b90565b600154600160a01b900460ff1681565b6000806000611473878787876000610a79565b9250925092509450945094915050565b6001546001600160a01b031633146114cc5760405162461bcd60e51b8152600401808060200182810382526023815260200180611f986023913960400191505060405180910390fd5b600154600160a01b900460ff161561152b576040805162461bcd60e51b815260206004820152601f60248201527f416363657373436f6e74726f6c3a2063757272656e746c792070617573656400604482015290519081900360640190fd5b6001805460ff60a01b1916600160a01b1790556040517f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e75290600090a1565b600654610100900460ff1681565b60076020526000908152604090205460ff1681565b6000546001600160a01b031633146115d9576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b6001600160a01b03166000908152600760205260409020805460ff19169055565b6006546201000090046001600160a01b031681565b60065460009060ff610100909104161515600114611674576040805162461bcd60e51b815260206004820152601e60248201527f506f696e7465723a20646973747269627574696f6e2064697361626c65640000604482015290519081900360640190fd5b506001600160a01b038082166000818152600860209081526040808320805490849055600654825163a9059cbb60e01b815260048101969096526024860182905291519095620100009092049091169363a9059cbb9360448083019493928390030190829087803b1580156116e857600080fd5b505af11580156116fc573d6000803e3d6000fd5b505050506040513d602081101561171257600080fd5b509092915050565b6000546001600160a01b03163314611767576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b6001600160a01b03166000908152600760205260409020805460ff19166001179055565b60065460ff1681565b60005b81518110156117c5576117bc8282815181106117af57fe5b602002602001015161160f565b50600101611797565b5050565b6001600160a01b03811661180e5760405162461bcd60e51b8152600401808060200182810382526025815260200180611eee6025913960400191505060405180910390fd5b6000546001600160a01b031633148061183157506001546001600160a01b031633145b61186c5760405162461bcd60e51b8152600401808060200182810382526025815260200180611eee6025913960400191505060405180910390fd5b600180546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517f54841e992da2f7bcaa3127409f02e1849c79072740593c398d6670f65f995fa7916020908290030190a150565b6000546001600160a01b03163314611913576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b600680549115156101000261ff0019909216919091179055565b6001546001600160a01b031681565b600c602052600090815260409020546001600160a01b031681565b600a6020526000908152604090205481565b60055481565b600960209081526000928352604080842090915290825290205481565b600e5481565b6000546001600160a01b031633146119df576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b60048190556040805182815290517f0db3f0b95d380d43b2ec761145e6d8f1d66289c8353f838f4ccaa0e2866e3d4f9181900360200190a150565b600d5481565b6000546001600160a01b03163314611a6d576040805162461bcd60e51b81526020600482018190526024820152600080516020611f56833981519152604482015290519081900360640190fd5b600680546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6001600160a01b031660009081526007602052604090205460ff1690565b60008360011415611ac857506000611ae5565b600084118015611ad6575082155b611ae05782611ae2565b815b90505b9392505050565b60008084118015611ad657508215611ae05782611ae2565b600082820183811015611b5e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b6000808211611bbd576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b6000828481611bc857fe5b04949350505050565b600082611be057506000611b61565b82820282848281611bed57fe5b0414611b5e5760405162461bcd60e51b8152600401808060200182810382526021815260200180611fbb6021913960400191505060405180910390fd5b611c3382611dce565b156117c557611c526064610b80600d5484611bd190919063ffffffff16565b6001600160a01b039283166000908152600c602090815260408083205490951682526008905292909220805490920190915550565b6000806001611c9d611c9888611dee565b611e71565b84878760405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611cf4573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611d50576040805162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b604482015290519081900360640190fd5b866001600160a01b0316816001600160a01b03161491505095945050505050565b600033301415611dc95760606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b0316915061144d9050565b503390565b6001600160a01b039081166000908152600c602052604090205416151590565b6000604051806080016040528060438152602001611f1360439139805190602001208260000151836020015184604001518051906020012060405160200180858152602001848152602001836001600160a01b03168152602001828152602001945050505050604051602081830303815290604052805190602001209050919050565b6000611e7b611ebd565b82604051602001808061190160f01b81525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050919050565b60025490565b60405180606001604052806000815260200160006001600160a01b0316815260200160608152509056fe416363657373436f6e74726f6c3a20696e76616c696420776f726b657220616464726573734d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529416363657373436f6e74726f6c3a2043454f206163636573732064656e696564416363657373436f6e74726f6c3a20696e76616c69642043454f2061646472657373416363657373436f6e74726f6c3a20776f726b6572206163636573732064656e696564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775369676e657220616e64207369676e617475726520646f206e6f74206d61746368416363657373436f6e74726f6c3a2063757272656e6c7479206e6f7420706175736564506f696e7465723a20706c6179657220616c726561647920616666696c6961746564a26469706673582212202391db35bc15deb8a51dbc383483303a6573649a8508982aa38d83c9e20f37d064736f6c63430007040033