Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- GlobalStaking
- Optimization enabled
- true
- Compiler version
- v0.8.7+commit.e28d00a7
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:31:58.177447Z
Contract source code
// SPDX-License-Identifier: No License (None) pragma solidity ^0.8.0; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". * * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/contracts/ownership/Ownable.sol * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the * build/artifacts folder) as well as the vanilla Ownable implementation from an openzeppelin version. */ contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor () { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(),"Not Owner"); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * @notice Renouncing to ownership will leave the contract without an owner. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0),"Zero address not allowed"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } interface IERC223 { /** * @dev Returns the balance of the `who` address. */ function balanceOf(address who) external view returns (uint256); /** * @dev Transfers `value` tokens from `msg.sender` to `to` address * and returns `true` on success. */ function transfer(address to, uint256 value) external returns (bool success); /** * @dev Transfers `value` tokens from `msg.sender` to `to` address with `data` parameter * and returns `true` on success. */ function transfer( address to, uint256 value, bytes memory data ) external returns (bool success); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); function approve(address spender, uint256 amount) external returns (bool); function burn(uint256 amount) external returns (bool); /** * @dev Event that is fired on successful transfer. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Additional event that is fired on successful transfer and logs transfer metadata, * this event is implemented to keep Transfer event compatible with ERC20. */ event TransferData(bytes data); } interface ILocalFarm { function notifyRewardAmount(uint256 reward) external; function initialize( address _rewardsToken, // SOY token address _lpToken // LP token that will be staked in this Local Farm ) external; } interface ISimplifiedGlobalFarm { function mintFarmingReward(address _localFarm) external; function getAllocationX1000(address _farm) external view returns (uint256); function getRewardPerSecond() external view returns (uint256); function rewardMintingAvailable(address _farm) external view returns (bool); function farmExists(address _farmAddress) external view returns (bool); } contract GlobalStaking is Ownable { struct LocalFarm { address farmAddress; uint256 multiplier; uint256 lastPayment; } address public constant globalFarm = 0x64Fa36ACD0d13472FD786B03afC9C52aD5FCf023; address public constant SOY_TOKEN = 0x9FaE2529863bD691B4A7171bDfCf33C7ebB10a65; uint256 public totalMultipliers; uint256 public paymentDelay = 1 days; // DEFAULTS_TO 1 days mapping(uint256 => LocalFarm) public localFarms; uint256 public lastAddedFarmIndex = 0; // Farm IDs will start from 1 mapping(address => uint256) public localFarmId; // locals farm address => id; localFarm at ID = 0 is considered non-existing mapping(address => uint256) public nextMint; // timestamp when token may be minted to local farm event AddStaking(address _localFarm, uint32 _multiplier); event RemoveStaking(address _localFarm); event ChangeMultiplier(address _localFarm, uint256 _oldMultiplier, uint256 _newMultiplier); function next_payment() public view returns (uint256) { return (block.timestamp / paymentDelay) * paymentDelay + paymentDelay; } function rewardMintingAvailable(address _farm) public view returns (bool) { return localFarms[localFarmId[_farm]].lastPayment + paymentDelay < next_payment(); } function getAllocationX1000(address _farm) public view returns (uint256) { return 1000 * localFarms[localFarmId[_farm]].multiplier / totalMultipliers; } function getRewardPerSecond() public view returns (uint256) { uint256 rewardPerSecond = ISimplifiedGlobalFarm(globalFarm).getRewardPerSecond(); uint256 allocationX1000 = ISimplifiedGlobalFarm(globalFarm).getAllocationX1000(address(this)); return rewardPerSecond * allocationX1000 / 1000; } function getLocalFarmId(address _localFarmAddress) external view returns (uint256) { return localFarmId[_localFarmAddress]; } function getLastPayment(address _localFarmAddress) external view returns (uint256) { return localFarms[localFarmId[_localFarmAddress]].lastPayment; } function addStakingContract( address _localFarmAddress, // staking contract uint32 _multiplier ) external onlyOwner { // Increment last index before adding a farm. // Farm with index = 0 is considered non-existing. lastAddedFarmIndex++; localFarms[lastAddedFarmIndex].farmAddress = _localFarmAddress; localFarms[lastAddedFarmIndex].multiplier = _multiplier; localFarms[lastAddedFarmIndex].lastPayment = next_payment() - paymentDelay; localFarmId[_localFarmAddress] = lastAddedFarmIndex; totalMultipliers += uint256(_multiplier); emit AddStaking(_localFarmAddress, _multiplier); } function farmExists(address _farmAddress) public view returns (bool _exists) { return (localFarmId[_farmAddress] != 0) && (localFarms[localFarmId[_farmAddress]].farmAddress != address(0)); } function removeLocalFarmByAddress(address _localFarmAddress) external onlyOwner { require (farmExists(_localFarmAddress), "LocalFarm with this address does not exist"); totalMultipliers = totalMultipliers - uint256(localFarms[localFarmId[_localFarmAddress]].multiplier); // update totalMultipliers //delete localFarmId[_localFarmAddress]; localFarms[localFarmId[_localFarmAddress]].farmAddress = address(0); localFarms[localFarmId[_localFarmAddress]].multiplier = 0; // Not critically important, can be removed for gas efficiency reasons. localFarms[localFarmId[_localFarmAddress]].lastPayment = 0; // Not critically important, can be removed for gas efficiency reasons. localFarmId[_localFarmAddress] = 0; emit RemoveStaking(_localFarmAddress); } function changeMultiplier(address _localFarmAddress, uint32 _multiplier) external onlyOwner { require (farmExists(_localFarmAddress), "LocalFarm with this address does not exist"); uint256 oldMultiplier = localFarms[localFarmId[_localFarmAddress]].multiplier; totalMultipliers = totalMultipliers + uint256(_multiplier) - uint256(oldMultiplier); // update totalMultipliers localFarms[localFarmId[_localFarmAddress]].multiplier = _multiplier; emit ChangeMultiplier(_localFarmAddress, oldMultiplier, _multiplier); } function mintFarmingReward(address _localFarmAddress) external { require (farmExists(_localFarmAddress), "LocalFarm with this address does not exist"); // Comparing against 0:00 UTC always // to enable withdrawals for full days only at any point within 24 hours of a day. if(localFarms[localFarmId[_localFarmAddress]].lastPayment + paymentDelay > next_payment()) { // Someone is requesting payment for a Local Farm that was paid recently. // Do nothing. return; } else { ISimplifiedGlobalFarm(globalFarm).mintFarmingReward(address(this)); uint256 _reward = (next_payment() - localFarms[localFarmId[_localFarmAddress]].lastPayment) * getRewardPerSecond() * getAllocationX1000(_localFarmAddress) / 1000; localFarms[localFarmId[_localFarmAddress]].lastPayment = next_payment(); IERC223(SOY_TOKEN).transfer(_localFarmAddress, _reward); ILocalFarm(_localFarmAddress).notifyRewardAmount(_reward); } } }
Contract ABI
[{"type":"event","name":"AddStaking","inputs":[{"type":"address","name":"_localFarm","internalType":"address","indexed":false},{"type":"uint32","name":"_multiplier","internalType":"uint32","indexed":false}],"anonymous":false},{"type":"event","name":"ChangeMultiplier","inputs":[{"type":"address","name":"_localFarm","internalType":"address","indexed":false},{"type":"uint256","name":"_oldMultiplier","internalType":"uint256","indexed":false},{"type":"uint256","name":"_newMultiplier","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RemoveStaking","inputs":[{"type":"address","name":"_localFarm","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"SOY_TOKEN","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addStakingContract","inputs":[{"type":"address","name":"_localFarmAddress","internalType":"address"},{"type":"uint32","name":"_multiplier","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeMultiplier","inputs":[{"type":"address","name":"_localFarmAddress","internalType":"address"},{"type":"uint32","name":"_multiplier","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"_exists","internalType":"bool"}],"name":"farmExists","inputs":[{"type":"address","name":"_farmAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAllocationX1000","inputs":[{"type":"address","name":"_farm","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLastPayment","inputs":[{"type":"address","name":"_localFarmAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLocalFarmId","inputs":[{"type":"address","name":"_localFarmAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRewardPerSecond","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"globalFarm","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastAddedFarmIndex","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"localFarmId","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"farmAddress","internalType":"address"},{"type":"uint256","name":"multiplier","internalType":"uint256"},{"type":"uint256","name":"lastPayment","internalType":"uint256"}],"name":"localFarms","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintFarmingReward","inputs":[{"type":"address","name":"_localFarmAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nextMint","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"next_payment","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"paymentDelay","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeLocalFarmByAddress","inputs":[{"type":"address","name":"_localFarmAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"rewardMintingAvailable","inputs":[{"type":"address","name":"_farm","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalMultipliers","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
Contract Creation Code
0x608060405262015180600255600060045534801561001c57600080fd5b50600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3610f1d8061006b6000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063da5b4ee71161007c578063da5b4ee71461034a578063e26eeff414610352578063eec8afed14610365578063f2fde38b1461036e578063f9d30f1814610381578063fb853d641461039457600080fd5b80638da5cb5b146102665780638f32d59b146102775780639c4ee5b01461028a578063a06bdde5146102e8578063b77f6b7514610321578063c2ab26511461034157600080fd5b80634599fef6116101155780634599fef6146101e15780634f3a1ff8146101ea5780635480b9551461021d5780635b17f50614610230578063648a7e201461024b578063715018a61461025e57600080fd5b8063127eaa23146101525780633460c114146101675780633bb1f4291461018f5780634381feba146101a5578063445c92c5146101ce575b600080fd5b610165610160366004610d45565b6103b4565b005b61017a610175366004610d23565b6104cf565b60405190151581526020015b60405180910390f35b610197610522565b604051908152602001610186565b6101976101b3366004610d23565b6001600160a01b031660009081526005602052604090205490565b61017a6101dc366004610d23565b61054c565b61019760015481565b6102057364fa36acd0d13472fd786b03afc9c52ad5fcf02381565b6040516001600160a01b039091168152602001610186565b61016561022b366004610d45565b610594565b610205739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b610165610259366004610d23565b6106c2565b610165610926565b6000546001600160a01b0316610205565b6000546001600160a01b0316331461017a565b6102c3610298366004610da7565b6003602052600090815260409020805460018201546002909201546001600160a01b03909116919083565b604080516001600160a01b039094168452602084019290925290820152606001610186565b6101976102f6366004610d23565b6001600160a01b03166000908152600560209081526040808320548352600390915290206002015490565b61019761032f366004610d23565b60066020526000908152604090205481565b61019760025481565b61019761099a565b610197610360366004610d23565b610aca565b61019760045481565b61016561037c366004610d23565b610b0d565b61016561038f366004610d23565b610b40565b6101976103a2366004610d23565b60056020526000908152604090205481565b6000546001600160a01b031633146103e75760405162461bcd60e51b81526004016103de90610dd9565b60405180910390fd5b6103f0826104cf565b61040c5760405162461bcd60e51b81526004016103de90610dfc565b6001600160a01b0382166000908152600560209081526040808320548352600390915290206001908101549054819061044c9063ffffffff851690610e46565b6104569190610e9f565b60019081556001600160a01b0384166000818152600560209081526040808320548352600382529182902063ffffffff87169401849055815192835282018490528101919091527ff73ac06bb532ce46127d55c58225dec0321642d3b5285f78433ad4b129807f379060600160405180910390a1505050565b6001600160a01b0381166000908152600560205260408120541580159061051c57506001600160a01b03828116600090815260056020908152604080832054835260039091529020541615155b92915050565b600254600090806105338142610e5e565b61053d9190610e80565b6105479190610e46565b905090565b6000610556610522565b600280546001600160a01b0385166000908152600560209081526040808320548352600390915290209091015461058d9190610e46565b1092915050565b6000546001600160a01b031633146105be5760405162461bcd60e51b81526004016103de90610dd9565b600480549060006105ce83610eb6565b90915550506004805460009081526003602052604080822080546001600160a01b0319166001600160a01b038716179055915481522063ffffffff82166001919091015560025461061d610522565b6106279190610e9f565b6004805460009081526003602090815260408083206002019490945591546001600160a01b03861682526005909252918220556001805463ffffffff84169290610672908490610e46565b9091555050604080516001600160a01b038416815263ffffffff831660208201527fd65c64ffc651b77d0559e80aceed4408c91b006279b8ec3ec971555b6b9f5099910160405180910390a15050565b6106cb816104cf565b6106e75760405162461bcd60e51b81526004016103de90610dfc565b6106ef610522565b600280546001600160a01b038416600090815260056020908152604080832054835260039091529020909101546107269190610e46565b111561072f5750565b60405163032453f160e51b81523060048201527364fa36acd0d13472fd786b03afc9c52ad5fcf0239063648a7e2090602401600060405180830381600087803b15801561077b57600080fd5b505af115801561078f573d6000803e3d6000fd5b5050505060006103e86107a183610aca565b6107a961099a565b6001600160a01b038516600090815260056020908152604080832054835260039091529020600201546107da610522565b6107e49190610e9f565b6107ee9190610e80565b6107f89190610e80565b6108029190610e5e565b905061080c610522565b6001600160a01b038316600081815260056020908152604080832054835260039091529081902060020192909255905163a9059cbb60e01b8152600481019190915260248101829052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b15801561088e57600080fd5b505af11580156108a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c69190610d85565b50604051633c6b16ab60e01b8152600481018290526001600160a01b03831690633c6b16ab90602401600060405180830381600087803b15801561090957600080fd5b505af115801561091d573d6000803e3d6000fd5b50505050505b50565b6000546001600160a01b031633146109505760405162461bcd60e51b81526004016103de90610dd9565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000807364fa36acd0d13472fd786b03afc9c52ad5fcf0236001600160a01b031663da5b4ee76040518163ffffffff1660e01b815260040160206040518083038186803b1580156109ea57600080fd5b505afa1580156109fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a229190610dc0565b60405163389bbbfd60e21b81523060048201529091506000907364fa36acd0d13472fd786b03afc9c52ad5fcf0239063e26eeff49060240160206040518083038186803b158015610a7257600080fd5b505afa158015610a86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aaa9190610dc0565b90506103e8610ab98284610e80565b610ac39190610e5e565b9250505090565b600180546001600160a01b03831660009081526005602090815260408083205483526003909152812090920154610b03906103e8610e80565b61051c9190610e5e565b6000546001600160a01b03163314610b375760405162461bcd60e51b81526004016103de90610dd9565b61092381610c56565b6000546001600160a01b03163314610b6a5760405162461bcd60e51b81526004016103de90610dd9565b610b73816104cf565b610b8f5760405162461bcd60e51b81526004016103de90610dfc565b6001600160a01b0381166000908152600560209081526040808320548352600390915290206001908101549054610bc69190610e9f565b60019081556001600160a01b0382166000818152600560208181526040808420805485526003835281852080546001600160a01b031916905580548552818520909601849055855484528084206002018490558484529181529190935591519081527f752eed3ce65b2ce43f311706c3ce8dd03ed5cb4f3091c0cd1d54a782ae461529910160405180910390a150565b6001600160a01b038116610cac5760405162461bcd60e51b815260206004820152601860248201527f5a65726f2061646472657373206e6f7420616c6c6f776564000000000000000060448201526064016103de565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b0381168114610d1e57600080fd5b919050565b600060208284031215610d3557600080fd5b610d3e82610d07565b9392505050565b60008060408385031215610d5857600080fd5b610d6183610d07565b9150602083013563ffffffff81168114610d7a57600080fd5b809150509250929050565b600060208284031215610d9757600080fd5b81518015158114610d3e57600080fd5b600060208284031215610db957600080fd5b5035919050565b600060208284031215610dd257600080fd5b5051919050565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b6020808252602a908201527f4c6f63616c4661726d20776974682074686973206164647265737320646f6573604082015269081b9bdd08195e1a5cdd60b21b606082015260800190565b60008219821115610e5957610e59610ed1565b500190565b600082610e7b57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615610e9a57610e9a610ed1565b500290565b600082821015610eb157610eb1610ed1565b500390565b6000600019821415610eca57610eca610ed1565b5060010190565b634e487b7160e01b600052601160045260246000fdfea264697066735822122087b78895cac42e4a9194f6d0eeaca1521ed6f258c181da340a1edc42cc0f9ed964736f6c63430008070033
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063da5b4ee71161007c578063da5b4ee71461034a578063e26eeff414610352578063eec8afed14610365578063f2fde38b1461036e578063f9d30f1814610381578063fb853d641461039457600080fd5b80638da5cb5b146102665780638f32d59b146102775780639c4ee5b01461028a578063a06bdde5146102e8578063b77f6b7514610321578063c2ab26511461034157600080fd5b80634599fef6116101155780634599fef6146101e15780634f3a1ff8146101ea5780635480b9551461021d5780635b17f50614610230578063648a7e201461024b578063715018a61461025e57600080fd5b8063127eaa23146101525780633460c114146101675780633bb1f4291461018f5780634381feba146101a5578063445c92c5146101ce575b600080fd5b610165610160366004610d45565b6103b4565b005b61017a610175366004610d23565b6104cf565b60405190151581526020015b60405180910390f35b610197610522565b604051908152602001610186565b6101976101b3366004610d23565b6001600160a01b031660009081526005602052604090205490565b61017a6101dc366004610d23565b61054c565b61019760015481565b6102057364fa36acd0d13472fd786b03afc9c52ad5fcf02381565b6040516001600160a01b039091168152602001610186565b61016561022b366004610d45565b610594565b610205739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b610165610259366004610d23565b6106c2565b610165610926565b6000546001600160a01b0316610205565b6000546001600160a01b0316331461017a565b6102c3610298366004610da7565b6003602052600090815260409020805460018201546002909201546001600160a01b03909116919083565b604080516001600160a01b039094168452602084019290925290820152606001610186565b6101976102f6366004610d23565b6001600160a01b03166000908152600560209081526040808320548352600390915290206002015490565b61019761032f366004610d23565b60066020526000908152604090205481565b61019760025481565b61019761099a565b610197610360366004610d23565b610aca565b61019760045481565b61016561037c366004610d23565b610b0d565b61016561038f366004610d23565b610b40565b6101976103a2366004610d23565b60056020526000908152604090205481565b6000546001600160a01b031633146103e75760405162461bcd60e51b81526004016103de90610dd9565b60405180910390fd5b6103f0826104cf565b61040c5760405162461bcd60e51b81526004016103de90610dfc565b6001600160a01b0382166000908152600560209081526040808320548352600390915290206001908101549054819061044c9063ffffffff851690610e46565b6104569190610e9f565b60019081556001600160a01b0384166000818152600560209081526040808320548352600382529182902063ffffffff87169401849055815192835282018490528101919091527ff73ac06bb532ce46127d55c58225dec0321642d3b5285f78433ad4b129807f379060600160405180910390a1505050565b6001600160a01b0381166000908152600560205260408120541580159061051c57506001600160a01b03828116600090815260056020908152604080832054835260039091529020541615155b92915050565b600254600090806105338142610e5e565b61053d9190610e80565b6105479190610e46565b905090565b6000610556610522565b600280546001600160a01b0385166000908152600560209081526040808320548352600390915290209091015461058d9190610e46565b1092915050565b6000546001600160a01b031633146105be5760405162461bcd60e51b81526004016103de90610dd9565b600480549060006105ce83610eb6565b90915550506004805460009081526003602052604080822080546001600160a01b0319166001600160a01b038716179055915481522063ffffffff82166001919091015560025461061d610522565b6106279190610e9f565b6004805460009081526003602090815260408083206002019490945591546001600160a01b03861682526005909252918220556001805463ffffffff84169290610672908490610e46565b9091555050604080516001600160a01b038416815263ffffffff831660208201527fd65c64ffc651b77d0559e80aceed4408c91b006279b8ec3ec971555b6b9f5099910160405180910390a15050565b6106cb816104cf565b6106e75760405162461bcd60e51b81526004016103de90610dfc565b6106ef610522565b600280546001600160a01b038416600090815260056020908152604080832054835260039091529020909101546107269190610e46565b111561072f5750565b60405163032453f160e51b81523060048201527364fa36acd0d13472fd786b03afc9c52ad5fcf0239063648a7e2090602401600060405180830381600087803b15801561077b57600080fd5b505af115801561078f573d6000803e3d6000fd5b5050505060006103e86107a183610aca565b6107a961099a565b6001600160a01b038516600090815260056020908152604080832054835260039091529020600201546107da610522565b6107e49190610e9f565b6107ee9190610e80565b6107f89190610e80565b6108029190610e5e565b905061080c610522565b6001600160a01b038316600081815260056020908152604080832054835260039091529081902060020192909255905163a9059cbb60e01b8152600481019190915260248101829052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b15801561088e57600080fd5b505af11580156108a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c69190610d85565b50604051633c6b16ab60e01b8152600481018290526001600160a01b03831690633c6b16ab90602401600060405180830381600087803b15801561090957600080fd5b505af115801561091d573d6000803e3d6000fd5b50505050505b50565b6000546001600160a01b031633146109505760405162461bcd60e51b81526004016103de90610dd9565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000807364fa36acd0d13472fd786b03afc9c52ad5fcf0236001600160a01b031663da5b4ee76040518163ffffffff1660e01b815260040160206040518083038186803b1580156109ea57600080fd5b505afa1580156109fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a229190610dc0565b60405163389bbbfd60e21b81523060048201529091506000907364fa36acd0d13472fd786b03afc9c52ad5fcf0239063e26eeff49060240160206040518083038186803b158015610a7257600080fd5b505afa158015610a86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aaa9190610dc0565b90506103e8610ab98284610e80565b610ac39190610e5e565b9250505090565b600180546001600160a01b03831660009081526005602090815260408083205483526003909152812090920154610b03906103e8610e80565b61051c9190610e5e565b6000546001600160a01b03163314610b375760405162461bcd60e51b81526004016103de90610dd9565b61092381610c56565b6000546001600160a01b03163314610b6a5760405162461bcd60e51b81526004016103de90610dd9565b610b73816104cf565b610b8f5760405162461bcd60e51b81526004016103de90610dfc565b6001600160a01b0381166000908152600560209081526040808320548352600390915290206001908101549054610bc69190610e9f565b60019081556001600160a01b0382166000818152600560208181526040808420805485526003835281852080546001600160a01b031916905580548552818520909601849055855484528084206002018490558484529181529190935591519081527f752eed3ce65b2ce43f311706c3ce8dd03ed5cb4f3091c0cd1d54a782ae461529910160405180910390a150565b6001600160a01b038116610cac5760405162461bcd60e51b815260206004820152601860248201527f5a65726f2061646472657373206e6f7420616c6c6f776564000000000000000060448201526064016103de565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b0381168114610d1e57600080fd5b919050565b600060208284031215610d3557600080fd5b610d3e82610d07565b9392505050565b60008060408385031215610d5857600080fd5b610d6183610d07565b9150602083013563ffffffff81168114610d7a57600080fd5b809150509250929050565b600060208284031215610d9757600080fd5b81518015158114610d3e57600080fd5b600060208284031215610db957600080fd5b5035919050565b600060208284031215610dd257600080fd5b5051919050565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b6020808252602a908201527f4c6f63616c4661726d20776974682074686973206164647265737320646f6573604082015269081b9bdd08195e1a5cdd60b21b606082015260800190565b60008219821115610e5957610e59610ed1565b500190565b600082610e7b57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615610e9a57610e9a610ed1565b500290565b600082821015610eb157610eb1610ed1565b500390565b6000600019821415610eca57610eca610ed1565b5060010190565b634e487b7160e01b600052601160045260246000fdfea264697066735822122087b78895cac42e4a9194f6d0eeaca1521ed6f258c181da340a1edc42cc0f9ed964736f6c63430008070033