Address Details
contract
0xb44c40D4232Ca00715Cd1a6fB47E80C798e8b8fb
- Contract Name
- UnergyLogicOperation
- Creator
- 0x4a47b6–0909dc at 0x111058–bcc580
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- 1,010 Transactions
- Transfers
- 31 Transfers
- Gas Used
- 92,710,952
- Last Balance Update
- 17334069
Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- UnergyLogicOperation
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 200
- EVM Version
- byzantium
- Verified at
- 2023-03-17T18:47:07.158198Z
project:/contracts/UnergyLogicOperation.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17.0; import "../node_modules/@openzeppelin/contracts/access/Ownable.sol"; import "../node_modules/@openzeppelin/contracts/security/Pausable.sol"; import "../node_modules/@openzeppelin/contracts/utils/math/Math.sol"; import "../node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "./DataStructure.sol"; import "./IUnergyData.sol"; abstract contract PermissionGranterAbs { function getPermission( address addressReq, address contractAddress, string memory fname ) public virtual returns(bool); } abstract contract ERC20Abs { function mint( address account, uint256 amount ) public virtual; function burn( address account, uint256 amount ) public virtual; function transferFrom( address from, address to, uint256 amount ) public virtual; function transfer( address to, uint256 amount ) public virtual; function burnFrom( address owner, uint256 amount ) public virtual; function balanceOf( address account ) public virtual returns(uint256); function approveSwap( address owner, address spender, uint256 amount ) public virtual; function allowance ( address owner, address spender ) public virtual returns(uint256); function decimals() public virtual returns(uint256); } abstract contract ERC1155Abs { function mint( address projectAddr, uint256 amount ) public virtual; function burn( address projectAddr, uint256 amount ) public virtual; } contract UnergyLogicOperation is ReentrancyGuard, Pausable, Ownable { ///@dev Variables IUnergyData public unergyData; address public unergyDataAddr; address public unergyLogicFundingAddr; address public cleanEnergyAssetsAddr; address public permissionGranterAddress; address public maintenanceAddress; address payable public recipient; ///@dev Events event ProjectCreated(DataStructure.Project project); event EnergyReport( address projectAddr, uint256 currentAccEnergy, uint256 deltaEnergy ); event InvoiceReport( address projectAddr, uint256 energyDelta, uint256 energyTariff, uint256 income, uint256 eventDepreciation ); ///@dev Contract Functions. constructor( address _unergyDataAddr, address _maintenanceAddr, address payable owner_ ) { unergyDataAddr = _unergyDataAddr; unergyData = IUnergyData(unergyDataAddr); maintenanceAddress = _maintenanceAddr;//does this goes here? recipient = owner_; } ///@dev Modifiers. modifier hasRoleInPermissionGranter( address _address, string memory _fname ) { PermissionGranterAbs permissionGranter = PermissionGranterAbs(permissionGranterAddress); bool permissionState = permissionGranter.getPermission( _address, address(this), _fname ); require(permissionState == true); _; } function setProjectSignature( address _projectAddr, uint256 _signatureProfile ) public whenNotPaused hasRoleInPermissionGranter( msg.sender, "setProjectSignature" ) { unergyData.setSignature( _projectAddr, _signatureProfile ); } function energyReport( address _projectAddr, uint256 _currentAccEnergy ) public whenNotPaused hasRoleInPermissionGranter( msg.sender, "energyReport" ) { ERC1155Abs cleanEnergyAssets = ERC1155Abs(cleanEnergyAssetsAddr); uint256 lastAccEnergy = unergyData.getAccEnergyByMeter( _projectAddr, msg.sender ); require( lastAccEnergy < _currentAccEnergy, "Accumulated energy must be greater than the registered energy" ); uint256 energyDelta = ( _currentAccEnergy- lastAccEnergy ); if (unergyData.getAccEnergyByMeter( _projectAddr, msg.sender ) == 0 ) { unergyData.setAccEnergyByMeter( _projectAddr, msg.sender, _currentAccEnergy ); } else { unergyData.setAccEnergyByMeter( _projectAddr, msg.sender, _currentAccEnergy ); cleanEnergyAssets.mint( _projectAddr, energyDelta ); } emit EnergyReport( _projectAddr, _currentAccEnergy, energyDelta ); } function externalInvoiceReport( address _projectAddr, address _stableCoindAddr, uint256 _amount, uint256 _energyDelta, uint256 _energyTariff, uint256 _depreciationPercentage ) public whenNotPaused hasRoleInPermissionGranter( msg.sender, "externalInvoiceReport" ) { DataStructure.Project memory project = unergyData.getProject(_projectAddr); uint256 maintenanceIncome = Math.mulDiv( _amount, project.maintenancePercentage, 10000 ); uint256 profitIncome = _amount - maintenanceIncome; ERC20Abs stableCoin = ERC20Abs(_stableCoindAddr); ///@dev transfer profitIncome funds to this contract stableCoin.transferFrom(msg.sender, address(this), profitIncome); ///@dev transfer maintenanceIncome funds to maintenance address stableCoin.transferFrom( msg.sender, maintenanceAddress, maintenanceIncome ); invoiceReport( _projectAddr, _amount, _energyDelta, _energyTariff, _depreciationPercentage ); } function invoiceReport( address _projectAddr, uint256 income, uint256 _energyDelta, uint256 _energyTariff, ///@dev Scaled value by 1e6; uint256 _depreciationPercentage ) internal { DataStructure.Project memory project = unergyData.getProject(_projectAddr); DataStructure.DepreciatedBalance memory depreciatedBalance = unergyData.getDepreciatedBalance(); DataStructure.Tokens memory tokens = project.tokens; uint256 totalSupply = tokens.pWatts; DataStructure.ProjectState state = project.state; uint256 eventDepreciation; if (state == DataStructure.ProjectState.INSTALLED) { eventDepreciation = 0; } else if (state == DataStructure.ProjectState.PRODUCTION) { ///@dev 1e8 value is scaling compensation uint256 pWattDepreciated = Math.mulDiv( totalSupply, _depreciationPercentage, 1e8 ); depreciatedBalance.pWattDepreciated += pWattDepreciated; project.pWattDepreciated += pWattDepreciated; ERC20Abs pWatt = ERC20Abs(_projectAddr); pWatt.burn( address(this), pWattDepreciated ); eventDepreciation = project.pWattDepreciated; } unergyData.updateProject( _projectAddr, project ); unergyData.setDepreciatedBalance(depreciatedBalance); ERC1155Abs cleanEnergyAssets = ERC1155Abs(cleanEnergyAssetsAddr); cleanEnergyAssets.burn( _projectAddr, _energyDelta ); emit InvoiceReport( _projectAddr, _energyDelta, _energyTariff, income, eventDepreciation ); } function pWattsTransfer( address _projectAddr, address _stableCoindAddr, address _receiver, uint256 _amount, uint256 _pWattPrice ) public hasRoleInPermissionGranter( msg.sender, "pWattsTransfer" ) { ERC20Abs stableCoin = ERC20Abs(_stableCoindAddr); DataStructure.Project memory project = unergyData.getProject(_projectAddr); DataStructure.Tokens memory token = project.tokens; uint256 decimals = stableCoin.decimals(); if(unergyData.getItIsInstitutionalAddress( _receiver, _projectAddr ) ) { token.pWatts -= _amount; token.eWatts += _amount; unergyData.updateProject(_projectAddr, project); } if(_receiver == unergyLogicFundingAddr) { stableCoin.transfer( project.adminAddr, _amount * _pWattPrice*(10**(decimals - 4)) ); _pWattsTransfer( _projectAddr, _receiver, _amount ); } else { stableCoinTransferFrom( _projectAddr, _stableCoindAddr, msg.sender, _receiver, _amount, _pWattPrice ); } } function stableCoinTransferFrom( address _projectAddr, address _stableCoindAddr, address sender, address _receiver, uint256 _amount, uint256 _pWattPrice ) internal { DataStructure.Project memory project = unergyData.getProject(_projectAddr); DataStructure.Tokens memory token = project.tokens; ERC20Abs pWatt = ERC20Abs(_projectAddr); ERC20Abs stableCoin = ERC20Abs(_stableCoindAddr); uint256 decimals = stableCoin.decimals(); stableCoin.transferFrom( sender, project.adminAddr, _amount * _pWattPrice * (10 ** (decimals - 4)) ); pWatt.transferFrom( project.adminAddr, _receiver, _amount ); pWatt.approveSwap( _receiver, address(this), token.pWatts ); } function _pWattsTransfer( address _projectAddr, address _receiver, uint256 _amount ) internal { ERC20Abs pWatt = ERC20Abs(_projectAddr); DataStructure.Project memory project = unergyData.getProject(_projectAddr); DataStructure.Tokens memory token = project.tokens; pWatt.transferFrom( project.adminAddr, _receiver, _amount ); pWatt.approveSwap( _receiver, address(this), token.pWatts ); } function swapToken(address _projectAddr) public hasRoleInPermissionGranter( msg.sender, "swapToken" ) { ERC20Abs pWatt = ERC20Abs(_projectAddr); DataStructure.Holders[] memory holders; holders = unergyData.getHolders(_projectAddr); DataStructure.Project memory project = unergyData.getProject(_projectAddr); DataStructure.HistoricalSwap memory historicalSwap; uint256 unergyUWatts; uint256 depreciatedPwatts; for (uint256 i; i < holders.length; i++) { bool isInstitutional = unergyData.getItIsInstitutionalAddress( holders[i].addr, _projectAddr ); uint256 pWattsPerHolder = pWatt.balanceOf(holders[i].addr); if(holders[i].addr == unergyLogicFundingAddr){ pWatt.transferFrom( holders[i].addr, address(this), pWattsPerHolder ); DataStructure.DepreciatedBalance memory depreciatedBalance = unergyData.getDepreciatedBalance(); ///@dev If pWatt balance depreciation is less than // pWatt balance on a particular project then all pWatts // for reserve will be for compensation of depreciation if (depreciatedBalance.pWattDepreciated < pWattsPerHolder){ ///@dev Generate uWatts unergyUWatts = Math.mulDiv( (pWattsPerHolder - depreciatedBalance.pWattDepreciated), project.swapFactor, 100 ); uWattsTransfer(holders[i].addr, unergyUWatts); ///@dev All Depreciated pWatts are compensated depreciatedPwatts = depreciatedBalance.pWattDepreciated; depreciatedBalance.pWattDepreciated -= depreciatedPwatts; } else { ///@dev No uWatts generated unergyUWatts = 0; ///@dev Depreciation is equal to pWatts depreciatedPwatts = pWattsPerHolder; depreciatedBalance.pWattDepreciated -= depreciatedPwatts; } unergyData.setDepreciatedBalance(depreciatedBalance); } else { if(pWattsPerHolder != 0 && !isInstitutional){ pWatt.transferFrom( holders[i].addr, address(this), pWattsPerHolder ); uWattsTransfer( holders[i].addr, Math.mulDiv( pWattsPerHolder, project.swapFactor, 100 ) ); } } } historicalSwap.uWattsUnergy = unergyUWatts; historicalSwap.totalUWatts = unergyData.getTotalPWatts(_projectAddr) - depreciatedPwatts; historicalSwap.totalSupplyAccumulated += historicalSwap.totalUWatts; unergyData.setHistoricalSwaps(historicalSwap); } function customSwap( address _projectAddr ) public nonReentrant { ERC20Abs pWatt = ERC20Abs(_projectAddr); DataStructure.Project memory project = unergyData.getProject(_projectAddr); uint256 amount = pWatt.balanceOf(msg.sender); DataStructure.Tokens memory token = project.tokens; DataStructure.DepreciatedBalance memory depreciatedBalance = unergyData.getDepreciatedBalance(); ///@dev Burn calculate and burn tokens uint256 depreciatedPwatts = project.pWattDepreciated; uint256 totalPwatts = token.pWatts; uint256 percentageToDepreciate = Math.mulDiv( depreciatedPwatts, 100000, totalPwatts ); uint256 pWattsToBurn = Math.mulDiv( amount, percentageToDepreciate, 100000 ); pWatt.burnFrom(msg.sender, pWattsToBurn); ///@dev convert eWatts for pWatts if msg sender is institutional if(unergyData.getItIsInstitutionalAddress( msg.sender, _projectAddr ) ) { token.pWatts += amount; token.eWatts -= amount; unergyData.updateProject(_projectAddr, project); } ///@dev pWatts transferFrom uint256 pWattsAfterBurn = pWatt.balanceOf(msg.sender); pWatt.transferFrom( msg.sender, address(this), pWattsAfterBurn ); ///@dev uWatts transfer uWattsTransfer( msg.sender, Math.mulDiv( pWattsAfterBurn, project.swapFactor, 100 ) ); } function uWattsTransfer( address _receiver, uint256 _amount ) internal virtual { address uWattAddress = unergyData.getUWattAddress(); ERC20Abs uWatt = ERC20Abs(uWattAddress); uWatt.mint(_receiver, _amount); } function updateLastUWattStatus ( address _sender, address _receiver, uint256 _amount ) public whenNotPaused hasRoleInPermissionGranter( msg.sender, "updateLastUWattStatus" ) { DataStructure.UWattStatus[] memory senderUWattStatusList = unergyData.getHolderUWattStatus(_sender); DataStructure.UWattStatus[] memory receiverUWattStatusList = unergyData.getHolderUWattStatus(_receiver); bool isFunding; if(_sender == unergyLogicFundingAddr){ isFunding = true; }else{ isFunding = false; } uint256 claimNumber = unergyData.getHistoricalSwapLength(); if (_sender != address(0)) { DataStructure.UWattStatus memory lastSenderUWattStatus; if(senderUWattStatusList.length == 0){ lastSenderUWattStatus.uWattsSold = _amount; lastSenderUWattStatus.totalUWatts = _amount; lastSenderUWattStatus.claimStatus = true; lastSenderUWattStatus.claimNumber = claimNumber; unergyData.setHolderUWattStatus( _sender, lastSenderUWattStatus ); } else { lastSenderUWattStatus = senderUWattStatusList[senderUWattStatusList.length -1]; lastSenderUWattStatus.uWattsSold += _amount; lastSenderUWattStatus.totalUWatts += _amount; unergyData.updateHolderUWattStatus( _sender, lastSenderUWattStatus ); } } if(_receiver != address(0)) { DataStructure.UWattStatus memory lastReceiverUWattStatus; if(receiverUWattStatusList.length == 0){ lastReceiverUWattStatus.uWattsPurchased = _amount; lastReceiverUWattStatus.totalUWatts = _amount; lastReceiverUWattStatus.claimStatus = true; lastReceiverUWattStatus.claimNumber = claimNumber; unergyData.setHolderUWattStatus( _receiver, lastReceiverUWattStatus ); } else { lastReceiverUWattStatus = receiverUWattStatusList[receiverUWattStatusList.length - 1]; if(!isFunding){ lastReceiverUWattStatus.uWattsPurchased += _amount; lastReceiverUWattStatus.totalUWatts += _amount; unergyData.updateHolderUWattStatus( _receiver, lastReceiverUWattStatus ); } else { unergyData.updateHolderUWattStatus( _receiver, lastReceiverUWattStatus ); unergyData.setNextHolderUWattStatus( _receiver, lastReceiverUWattStatus ); } } } } function claimUWatts( address _user, DataStructure.UWattStatus memory actualClaim, DataStructure.UWattStatus memory previousClaim ) internal whenNotPaused { DataStructure.HistoricalSwap[] memory historicalSwaps = unergyData.getHistoricalSwap(); actualClaim.uWattsCurrentClaim = historicalSwaps[actualClaim.claimNumber].uWattsUnergy; uint256 totalSupplyAcc = historicalSwaps[previousClaim.claimNumber].totalSupplyAccumulated; actualClaim.percentageToClaim = Math.mulDiv( actualClaim.currentUWatts, 10000000000, totalSupplyAcc ); actualClaim.uWattsClaimed = Math.mulDiv( actualClaim.uWattsCurrentClaim, actualClaim.percentageToClaim, 10000000000 ); actualClaim.claimStatus = true; actualClaim.totalUWatts = actualClaim.currentUWatts + actualClaim.uWattsPurchased + actualClaim.uWattsClaimed - actualClaim.uWattsSold; unergyData.updateHolderUWattStatus(_user, actualClaim); ///@dev transfer uWatts claimed address uWattAddress = unergyData.getUWattAddress(); ERC20Abs uWatt = ERC20Abs(uWattAddress); uWatt.transferFrom( unergyLogicFundingAddr, _user, actualClaim.uWattsClaimed ); } function iterativeClaim() public whenNotPaused { DataStructure.UWattStatus[] memory userUWattStatusList = unergyData.getHolderUWattStatus(msg.sender); uint256 historicalSwapLength = unergyData.getHistoricalSwapLength(); uint256 firstClaimNumber = userUWattStatusList[0].claimNumber; uint256 lastClaimNumber; for (uint256 i; i < historicalSwapLength; i++) { if(userUWattStatusList[i].claimStatus == false) { lastClaimNumber = userUWattStatusList[i].claimNumber; break; } } if(firstClaimNumber == 0){ for (uint256 i = lastClaimNumber; i < historicalSwapLength; i++) { claimUWatts( msg.sender, userUWattStatusList[i], userUWattStatusList[i - 1] ); userUWattStatusList = unergyData.getHolderUWattStatus(msg.sender); } } else { for( uint256 i = lastClaimNumber - firstClaimNumber; i < historicalSwapLength - firstClaimNumber; i++ ) { claimUWatts( msg.sender, userUWattStatusList[i], userUWattStatusList[i - 1] ); userUWattStatusList = unergyData.getHolderUWattStatus(msg.sender); } } } ///@dev set UnergyLogicFunding contract address function setUnergyLogicFundingAddr(address _address) public whenNotPaused onlyOwner { unergyLogicFundingAddr = _address; } ///@dev set CleanEnergyAssets contract address function setCleanEnergyAssetsAddr(address _address) public whenNotPaused onlyOwner { cleanEnergyAssetsAddr = _address; } function setPermissionGranterAddr(address _addr) public whenNotPaused onlyOwner { permissionGranterAddress = _addr; } ///@dev Ownable methods overridden function transferOwnership(address newOwner) public whenNotPaused override onlyOwner { require( newOwner != address(0), "Ownable: new owner cannot be the zero address" ); _transferOwnership(newOwner); } ///@dev Pausable method function pauseContract() public onlyOwner whenNotPaused { _pause(); } ///@dev Pausable method function unPauseContract() public onlyOwner whenNotPaused { _unpause(); } function closeContract() public onlyOwner { selfdestruct(recipient); } }
/project_/contracts/DataStructure.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17.0; library DataStructure { enum ProjectState { FUNDING, INSTALLED, PRODUCTION, CLOSED, CANCELLED } struct PWattPrice { uint256 initialValue; uint256 finalValue; } struct Tokens { uint256 pWatts; uint256 eWatts; } struct Project { uint256 idProject; uint256 maintenancePercentage; PWattPrice pWattPrice; uint256 swapFactor; ProjectState state; address projectAddr; address adminAddr; address installerAddr; uint256 pWattDepreciated; Tokens tokens; } struct Holders { address addr; bool fiat; } struct DepreciatedBalance { uint256 pWattDepreciated; } struct Milestone { string name; bool state; uint256 weight; bool installerSignature; bool unergySignature; } enum ProjectType { pWatt, eWatt } struct HistoricalSwap { uint256 id; uint256 uWattsUnergy; uint256 totalUWatts; uint256 totalSupplyAccumulated; } struct UWattStatus { uint256 currentUWatts; uint256 uWattsSold; uint256 uWattsPurchased; uint256 claimNumber; uint256 uWattsCurrentClaim; uint256 percentageToClaim; uint256 uWattsClaimed; uint256 totalUWatts; bool claimStatus; } }
/project_/contracts/IUnergyData.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17.0; import "./DataStructure.sol"; interface IUnergyData { ///@dev Set Functions function setProject( DataStructure.Project memory project ) external; function setHolders( address projectAddr, address holder ) external; function setUWattsAddr(address uWattsAddr) external; function setMilestone( address projectAddr, string memory name, uint256 weight ) external; function setMilestones( address projectAddr, DataStructure.Milestone[] memory milestone ) external; function setSignature( address projectAddr, uint256 signatureProfile ) external; function setDepreciatedBalance( DataStructure.DepreciatedBalance memory depreciatedBalance ) external; function setAccEnergyByMeter( address projectAddr, address meterAddr, uint256 accEnergy ) external; function setHistoricalSwaps( DataStructure.HistoricalSwap memory historicalSwap ) external; function setHolderUWattStatus( address holderAddress, DataStructure.UWattStatus memory uWattStatus ) external; function setNextHolderUWattStatus( address holderAddress, DataStructure.UWattStatus memory uWattStatus ) external; function updateHolderUWattStatus ( address holderAddress, DataStructure.UWattStatus memory uWattStatus ) external; function updateProject( address projectAddr, DataStructure.Project memory project ) external; function updateMilestones( address projectAddr, DataStructure.Milestone[] memory milestone, uint256 index ) external; function deleteMilestone( address projectAddr, uint256 index ) external; function setInstitutionalAddress( address userAddress, address projectAddress, bool state ) external; ///@dev Get Functions function getProject( address projectAddr ) external returns(DataStructure.Project memory); function getDepreciatedBalance() external returns (DataStructure.DepreciatedBalance memory); function getUWattAddress() external returns(address); function getHistoricalSwap() external returns(DataStructure.HistoricalSwap[] memory); function getHolderUWattStatus( address holderAddress ) external returns (DataStructure.UWattStatus[] memory); function getTotalPWatts( address projectAddr ) external returns(uint256); function getProjectState( address projectAddr ) external returns(DataStructure.ProjectState); function getHolders( address projectAddr ) external returns(DataStructure.Holders[] memory); function getMilestones( address projectAddr ) external returns(DataStructure.Milestone[] memory); function getSignatures( address projectAddr )external returns(bool[2] memory); function getAccEnergyByMeter( address projectAddr, address meterAddr ) external returns(uint256); function getItIsInstitutionalAddress( address userAddress, address projectAddress ) external returns(bool); function getHistoricalSwapLength() external returns(uint256); }
/project_/node_modules/_openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity 0.8.17.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
/project_/node_modules/_openzeppelin/contracts/security/Pausable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
/project_/node_modules/_openzeppelin/contracts/security/ReentrancyGuard.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity 0.8.17.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
/project_/node_modules/_openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity 0.8.17.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
/project_/node_modules/_openzeppelin/contracts/utils/math/Math.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_unergyDataAddr","internalType":"address"},{"type":"address","name":"_maintenanceAddr","internalType":"address"},{"type":"address","name":"owner_","internalType":"address payable"}]},{"type":"event","name":"EnergyReport","inputs":[{"type":"address","name":"projectAddr","internalType":"address","indexed":false},{"type":"uint256","name":"currentAccEnergy","internalType":"uint256","indexed":false},{"type":"uint256","name":"deltaEnergy","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"InvoiceReport","inputs":[{"type":"address","name":"projectAddr","internalType":"address","indexed":false},{"type":"uint256","name":"energyDelta","internalType":"uint256","indexed":false},{"type":"uint256","name":"energyTariff","internalType":"uint256","indexed":false},{"type":"uint256","name":"income","internalType":"uint256","indexed":false},{"type":"uint256","name":"eventDepreciation","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":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"ProjectCreated","inputs":[{"type":"tuple","name":"project","internalType":"struct DataStructure.Project","indexed":false,"components":[{"type":"uint256","name":"idProject","internalType":"uint256"},{"type":"uint256","name":"maintenancePercentage","internalType":"uint256"},{"type":"tuple","name":"pWattPrice","internalType":"struct DataStructure.PWattPrice","components":[{"type":"uint256","name":"initialValue","internalType":"uint256"},{"type":"uint256","name":"finalValue","internalType":"uint256"}]},{"type":"uint256","name":"swapFactor","internalType":"uint256"},{"type":"uint8","name":"state","internalType":"enum DataStructure.ProjectState"},{"type":"address","name":"projectAddr","internalType":"address"},{"type":"address","name":"adminAddr","internalType":"address"},{"type":"address","name":"installerAddr","internalType":"address"},{"type":"uint256","name":"pWattDepreciated","internalType":"uint256"},{"type":"tuple","name":"tokens","internalType":"struct DataStructure.Tokens","components":[{"type":"uint256","name":"pWatts","internalType":"uint256"},{"type":"uint256","name":"eWatts","internalType":"uint256"}]}]}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"cleanEnergyAssetsAddr","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"closeContract","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"customSwap","inputs":[{"type":"address","name":"_projectAddr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"energyReport","inputs":[{"type":"address","name":"_projectAddr","internalType":"address"},{"type":"uint256","name":"_currentAccEnergy","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"externalInvoiceReport","inputs":[{"type":"address","name":"_projectAddr","internalType":"address"},{"type":"address","name":"_stableCoindAddr","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint256","name":"_energyDelta","internalType":"uint256"},{"type":"uint256","name":"_energyTariff","internalType":"uint256"},{"type":"uint256","name":"_depreciationPercentage","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"iterativeClaim","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"maintenanceAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pWattsTransfer","inputs":[{"type":"address","name":"_projectAddr","internalType":"address"},{"type":"address","name":"_stableCoindAddr","internalType":"address"},{"type":"address","name":"_receiver","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint256","name":"_pWattPrice","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pauseContract","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"permissionGranterAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"recipient","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCleanEnergyAssetsAddr","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPermissionGranterAddr","inputs":[{"type":"address","name":"_addr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setProjectSignature","inputs":[{"type":"address","name":"_projectAddr","internalType":"address"},{"type":"uint256","name":"_signatureProfile","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setUnergyLogicFundingAddr","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"swapToken","inputs":[{"type":"address","name":"_projectAddr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unPauseContract","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IUnergyData"}],"name":"unergyData","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"unergyDataAddr","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"unergyLogicFundingAddr","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateLastUWattStatus","inputs":[{"type":"address","name":"_sender","internalType":"address"},{"type":"address","name":"_receiver","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]}]
Contract Creation Code
0x60806040523480156200001157600080fd5b506040516200411538038062004115833981016040819052620000349162000130565b60016000819055805460ff19169055620000696200005a640100000000620000b9810204565b640100000000620000bd810204565b60038054600160a060020a03948516600160a060020a0319918216811790925560028054821690921790915560078054938516938216939093179092556008805491909316911617905562000184565b3390565b60018054600160a060020a0383811661010081810261010060a860020a031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600160a060020a03811681146200012d57600080fd5b50565b6000806000606084860312156200014657600080fd5b8351620001538162000117565b6020850151909350620001668162000117565b6040850151909250620001798162000117565b809150509250925092565b613f8180620001946000396000f3fe608060405234801561001057600080fd5b50600436106101775760003560e060020a90048063610be654116100e25780638da5cb5b1161009b578063acc7b76a11610075578063acc7b76a14610304578063bac1520314610317578063f2fde38b1461031f578063f5dfe83a1461033257600080fd5b80638da5cb5b146102c8578063993d10dc146102de578063a37f3d52146102f157600080fd5b8063610be6541461026c57806366d003ac146102745780636e8d82af14610287578063704689771461029a578063715018a6146102ad578063719d5f83146102b557600080fd5b80633e83422e116101345780633e83422e14610202578063439766ce14610215578063456601d71461021d5780635594c630146102305780635b007e08146102435780635c975abb1461025657600080fd5b8063051be3741461017c57806328eeb6e1146101ac5780632d765a3f146101bf57806332917237146101d257806337cf8bf6146101e5578063387fe829146101ef575b600080fd5b60045461018f90600160a060020a031681565b604051600160a060020a0390911681526020015b60405180910390f35b60065461018f90600160a060020a031681565b60035461018f90600160a060020a031681565b60025461018f90600160a060020a031681565b6101ed610345565b005b6101ed6101fd366004613533565b610687565b6101ed610210366004613574565b610cb8565b6101ed610cf7565b6101ed61022b366004613591565b610d11565b6101ed61023e366004613574565b610e63565b6101ed610251366004613574565b610ea2565b60015460ff1660405190151581526020016101a3565b6101ed61133b565b60085461018f90600160a060020a031681565b6101ed610295366004613574565b611351565b6101ed6102a83660046135bd565b611b18565b6101ed611ef4565b60075461018f90600160a060020a031681565b6001546101009004600160a060020a031661018f565b6101ed6102ec366004613618565b611f06565b6101ed6102ff366004613574565b612159565b60055461018f90600160a060020a031681565b6101ed612198565b6101ed61032d366004613574565b6121b0565b6101ed610340366004613591565b61224d565b61034d6126a0565b60025460405160e260020a630aae3b7b028152336004820152600091600160a060020a031690632ab8edec906024016000604051808303816000875af115801561039b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103c39190810190613788565b90506000600260009054906101000a9004600160a060020a0316600160a060020a031663bd4546066040518163ffffffff1660e060020a0281526004016020604051808303816000875af115801561041f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104439190613890565b905060008260008151811061045a5761045a6138a9565b60200260200101516060015190506000805b838110156104d557848181518110610486576104866138a9565b60200260200101516101000151151560001515036104c3578481815181106104b0576104b06138a9565b60200260200101516060015191506104d5565b806104cd816138db565b91505061046c565b50816000036105c057805b838110156105ba57610531338683815181106104fe576104fe6138a9565b60200260200101518760018561051491906138f4565b81518110610524576105246138a9565b60200260200101516126f6565b60025460405160e260020a630aae3b7b028152336004820152600160a060020a0390911690632ab8edec906024016000604051808303816000875af115801561057e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105a69190810190613788565b9450806105b2816138db565b9150506104e0565b50610681565b60006105cc83836138f4565b90505b6105d983856138f4565b81101561067f576105f6338683815181106104fe576104fe6138a9565b60025460405160e260020a630aae3b7b028152336004820152600160a060020a0390911690632ab8edec906024016000604051808303816000875af1158015610643573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261066b9190810190613788565b945080610677816138db565b9150506105cf565b505b50505050565b61068f6126a0565b604080518082018252601581527f7570646174654c617374555761747453746174757300000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb9906106fd9087903090889060040161390d565b6020604051808303816000875af115801561071c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107409190613978565b905060018115151461075157600080fd5b60025460405160e260020a630aae3b7b028152600160a060020a0389811660048301526000921690632ab8edec906024016000604051808303816000875af11580156107a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107c99190810190613788565b60025460405160e260020a630aae3b7b028152600160a060020a038a8116600483015292935060009290911690632ab8edec906024016000604051808303816000875af115801561081e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108469190810190613788565b600454909150600090600160a060020a03908116908b160361086a5750600161086e565b5060005b600254604080517fbd4546060000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163bd454606916004808301926020929190829003018187875af11580156108d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f69190613890565b9050600160a060020a038b1615610a765761090f6134d0565b84516000036109b757602081018a905260e081018a90526001610100820152606081018290526002546040517f147dcb91000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063147dcb9190610980908f908590600401613993565b600060405180830381600087803b15801561099a57600080fd5b505af11580156109ae573d6000803e3d6000fd5b50505050610a74565b84600186516109c691906138f4565b815181106109d6576109d66138a9565b6020026020010151905089816020018181516109f29190613a0d565b90525060e0810180518b9190610a09908390613a0d565b90525060025460405160e460020a6305e669cd028152600160a060020a0390911690635e669cd090610a41908f908590600401613993565b600060405180830381600087803b158015610a5b57600080fd5b505af1158015610a6f573d6000803e3d6000fd5b505050505b505b600160a060020a038a1615610cab57610a8d6134d0565b8351600003610b355760408082018b905260e082018b905260016101008301526060820183905260025490517f147dcb91000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063147dcb9190610afe908e908590600401613993565b600060405180830381600087803b158015610b1857600080fd5b505af1158015610b2c573d6000803e3d6000fd5b50505050610ca9565b8360018551610b4491906138f4565b81518110610b5457610b546138a9565b6020026020010151905082610bc4578981604001818151610b759190613a0d565b90525060e0810180518b9190610b8c908390613a0d565b90525060025460405160e460020a6305e669cd028152600160a060020a0390911690635e669cd090610afe908e908590600401613993565b60025460405160e460020a6305e669cd028152600160a060020a0390911690635e669cd090610bf9908e908590600401613993565b600060405180830381600087803b158015610c1357600080fd5b505af1158015610c27573d6000803e3d6000fd5b50506002546040517fc0deaf4d000000000000000000000000000000000000000000000000000000008152600160a060020a03909116925063c0deaf4d9150610c76908e908590600401613993565b600060405180830381600087803b158015610c9057600080fd5b505af1158015610ca4573d6000803e3d6000fd5b505050505b505b5050505050505050505050565b610cc06126a0565b610cc861299f565b6006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b610cff61299f565b610d076126a0565b610d0f612a02565b565b610d196126a0565b604080518082018252601381527f73657450726f6a6563745369676e6174757265000000000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb990610d879087903090889060040161390d565b6020604051808303816000875af1158015610da6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dca9190613978565b9050600181151514610ddb57600080fd5b6002546040517f42e28ff4000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015260248201889052909116906342e28ff4906044015b600060405180830381600087803b158015610e4357600080fd5b505af1158015610e57573d6000803e3d6000fd5b50505050505050505050565b610e6b6126a0565b610e7361299f565b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b610eaa612a56565b60025460405160e060020a63f9870705028152600160a060020a038084166004830152839260009291169063f987070590602401610180604051808303816000875af1158015610efe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f229190613a6a565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152909150600090600160a060020a038416906370a08231906024016020604051808303816000875af1158015610f87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fab9190613890565b9050600082610120015190506000600260009054906101000a9004600160a060020a0316600160a060020a0316632ed1fd7e6040518163ffffffff1660e060020a0281526004016020604051808303816000875af1158015611011573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110359190613b1a565b610100850151835191925090600061105183620186a084612ab2565b905060006110638783620186a0612ab2565b6040517f79cc679000000000000000000000000000000000000000000000000000000000815233600482015260248101829052909150600160a060020a038a16906379cc679090604401600060405180830381600087803b1580156110c757600080fd5b505af11580156110db573d6000803e3d6000fd5b50506002546040517fb27ef15d000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038e81166024830152909116925063b27ef15d91506044016020604051808303816000875af115801561114a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116e9190613978565b1561121d5786866000018181516111859190613a0d565b90525060208601805188919061119c9083906138f4565b9052506002546040517ffa5a6f7e000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063fa5a6f7e906111ea908d908c90600401613b9a565b600060405180830381600087803b15801561120457600080fd5b505af1158015611218573d6000803e3d6000fd5b505050505b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090600160a060020a038b16906370a08231906024016020604051808303816000875af115801561127f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a39190613890565b60405160e060020a6323b872dd028152909150600160a060020a038b16906323b872dd906112d990339030908690600401613c73565b600060405180830381600087803b1580156112f357600080fd5b505af1158015611307573d6000803e3d6000fd5b505050506113243361131f838c606001516064612ab2565b612b67565b505050505050505050506113386001600055565b50565b61134361299f565b600854600160a060020a0316ff5b604080518082018252600981527f73776170546f6b656e00000000000000000000000000000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb9906113bf9087903090889060040161390d565b6020604051808303816000875af11580156113de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114029190613978565b905060018115151461141357600080fd5b6002546040517f38cac9ba000000000000000000000000000000000000000000000000000000008152600160a060020a03808816600483015287926060929116906338cac9ba906024016000604051808303816000875af115801561147c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114a49190810190613c97565b60025460405160e060020a63f9870705028152600160a060020a038a811660048301529293506000929091169063f987070590602401610180604051808303816000875af11580156114fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151e9190613a6a565b905061154b6040518060800160405280600081526020016000815260200160008152602001600081525090565b60008060005b85518110156119bf576002548651600091600160a060020a03169063b27ef15d90899085908110611584576115846138a9565b6020026020010151600001518f6040518363ffffffff1660e060020a0281526004016115c6929190600160a060020a0392831681529116602082015260400190565b6020604051808303816000875af11580156115e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116099190613978565b9050600088600160a060020a03166370a0823189858151811061162e5761162e6138a9565b60209081029190910101515160405160e060020a63ffffffff8416028152600160a060020a0390911660048201526024016020604051808303816000875af115801561167e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a29190613890565b6004548951919250600160a060020a0316908990859081106116c6576116c66138a9565b602002602001015160000151600160a060020a0316036118e55788600160a060020a03166323b872dd898581518110611701576117016138a9565b60200260200101516000015130846040518463ffffffff1660e060020a02815260040161173093929190613c73565b600060405180830381600087803b15801561174a57600080fd5b505af115801561175e573d6000803e3d6000fd5b505050506000600260009054906101000a9004600160a060020a0316600160a060020a0316632ed1fd7e6040518163ffffffff1660e060020a0281526004016020604051808303816000875af11580156117bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e09190613b1a565b9050818160000151101561184b57805161180a906117fe90846138f4565b89606001516064612ab2565b9550611833898581518110611821576118216138a9565b60200260200101516000015187612b67565b80519450848161184382806138f4565b905250611868565b60009550819450848160000181815161186491906138f4565b9052505b6002546040517fbacf3ae500000000000000000000000000000000000000000000000000000000815282516004820152600160a060020a039091169063bacf3ae590602401600060405180830381600087803b1580156118c757600080fd5b505af11580156118db573d6000803e3d6000fd5b50505050506119aa565b80158015906118f2575081155b156119aa5788600160a060020a03166323b872dd898581518110611918576119186138a9565b60200260200101516000015130846040518463ffffffff1660e060020a02815260040161194793929190613c73565b600060405180830381600087803b15801561196157600080fd5b505af1158015611975573d6000803e3d6000fd5b505050506119aa88848151811061198e5761198e6138a9565b60200260200101516000015161131f838a606001516064612ab2565b505080806119b7906138db565b915050611551565b50602083018290526002546040517f39777ec2000000000000000000000000000000000000000000000000000000008152600160a060020a038d81166004830152839216906339777ec2906024016020604051808303816000875af1158015611a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a509190613890565b611a5a91906138f4565b60408401819052606084018051611a72908390613a0d565b905250600254604080517f03e3155a000000000000000000000000000000000000000000000000000000008152855160048201526020860151602482015290850151604482015260608501516064820152600160a060020a03909116906303e3155a906084015b600060405180830381600087803b158015611af357600080fd5b505af1158015611b07573d6000803e3d6000fd5b505050505050505050505050505050565b604080518082018252600e81527f7057617474735472616e736665720000000000000000000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb990611b869087903090889060040161390d565b6020604051808303816000875af1158015611ba5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc99190613978565b9050600181151514611bda57600080fd5b60025460405160e060020a63f9870705028152600160a060020a038b811660048301528a9260009291169063f987070590602401610180604051808303816000875af1158015611c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c529190613a6a565b905060008161012001519050600083600160a060020a031663313ce5676040518163ffffffff1660e060020a0281526004016020604051808303816000875af1158015611ca3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc79190613890565b9050600260009054906101000a9004600160a060020a0316600160a060020a031663b27ef15d8c8f6040518363ffffffff1660e060020a028152600401611d24929190600160a060020a0392831681529116602082015260400190565b6020604051808303816000875af1158015611d43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d679190613978565b15611e15578982600001818151611d7e91906138f4565b9052506020820180518b9190611d95908390613a0d565b91508181525050600260009054906101000a9004600160a060020a0316600160a060020a031663fa5a6f7e8e856040518363ffffffff1660e060020a028152600401611de2929190613b9a565b600060405180830381600087803b158015611dfc57600080fd5b505af1158015611e10573d6000803e3d6000fd5b505050505b600454600160a060020a03908116908c1603611ed75783600160a060020a031663a9059cbb8460c00151600484611e4c91906138f4565b611e5790600a613e36565b611e618d8f613e42565b611e6b9190613e42565b60405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401600060405180830381600087803b158015611eaf57600080fd5b505af1158015611ec3573d6000803e3d6000fd5b50505050611ed28d8c8c612c75565b611ee5565b611ee58d8d338e8e8e612dab565b50505050505050505050505050565b611efc61299f565b610d0f6000612fe7565b611f0e6126a0565b604080518082018252601581527f65787465726e616c496e766f6963655265706f727400000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb990611f7c9087903090889060040161390d565b6020604051808303816000875af1158015611f9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fbf9190613978565b9050600181151514611fd057600080fd5b60025460405160e060020a63f9870705028152600160a060020a038c81166004830152600092169063f987070590602401610180604051808303816000875af1158015612021573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120459190613a6a565b9050600061205a8a8360200151612710612ab2565b90506000612068828c6138f4565b60405160e060020a6323b872dd0281529091508c90600160a060020a038216906323b872dd906120a090339030908790600401613c73565b600060405180830381600087803b1580156120ba57600080fd5b505af11580156120ce573d6000803e3d6000fd5b505060075460405160e060020a6323b872dd028152600160a060020a0380861694506323b872dd935061210a9233929116908890600401613c73565b600060405180830381600087803b15801561212457600080fd5b505af1158015612138573d6000803e3d6000fd5b505050506121498e8d8d8d8d61304e565b5050505050505050505050505050565b6121616126a0565b61216961299f565b6005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6121a061299f565b6121a86126a0565b610d0f613442565b6121b86126a0565b6121c061299f565b600160a060020a0381166122445760405160e560020a62461bcd02815260206004820152602d60248201527f4f776e61626c653a206e6577206f776e65722063616e6e6f742062652074686560448201527f207a65726f20616464726573730000000000000000000000000000000000000060648201526084015b60405180910390fd5b61133881612fe7565b6122556126a0565b604080518082018252600c81527f656e657267795265706f727400000000000000000000000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb9906122c39087903090889060040161390d565b6020604051808303816000875af11580156122e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123069190613978565b905060018115151461231757600080fd5b6005546002546040517fec26e894000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015233602483015292831692600092169063ec26e894906044016020604051808303816000875af115801561238a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ae9190613890565b90508681106124285760405160e560020a62461bcd02815260206004820152603d60248201527f416363756d756c6174656420656e65726779206d75737420626520677265617460448201527f6572207468616e20746865207265676973746572656420656e65726779000000606482015260840161223b565b600061243482896138f4565b6002546040517fec26e894000000000000000000000000000000000000000000000000000000008152600160a060020a038c8116600483015233602483015292935091169063ec26e894906044016020604051808303816000875af11580156124a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c59190613890565b600003612550576002546040517fa6be208b000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063a6be208b90612519908c9033908d90600401613c73565b600060405180830381600087803b15801561253357600080fd5b505af1158015612547573d6000803e3d6000fd5b5050505061264b565b6002546040517fa6be208b000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063a6be208b9061259d908c9033908d90600401613c73565b600060405180830381600087803b1580156125b757600080fd5b505af11580156125cb573d6000803e3d6000fd5b50506040517f40c10f19000000000000000000000000000000000000000000000000000000008152600160a060020a038c8116600483015260248201859052861692506340c10f199150604401600060405180830381600087803b15801561263257600080fd5b505af1158015612646573d6000803e3d6000fd5b505050505b60408051600160a060020a038b168152602081018a90529081018290527f785c4f42ebbc14b75395e9a6c4b77c1306f9a04d9707e9f3daab18e9ca14a4d89060600160405180910390a1505050505050505050565b60015460ff1615610d0f5760405160e560020a62461bcd02815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161223b565b6126fe6126a0565b600254604080517fe32c704e0000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163e32c704e9160048083019286929190829003018183875af1158015612761573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127899190810190613e59565b9050808360600151815181106127a1576127a16138a9565b6020026020010151602001518360800181815250506000818360600151815181106127ce576127ce6138a9565b60200260200101516060015190506127f084600001516402540be40083612ab2565b60a08501819052608085015161280b916402540be400612ab2565b60c0850181905260016101008601526020850151604086015186519192916128339190613a0d565b61283d9190613a0d565b61284791906138f4565b60e085015260025460405160e460020a6305e669cd028152600160a060020a0390911690635e669cd0906128819088908890600401613993565b600060405180830381600087803b15801561289b57600080fd5b505af11580156128af573d6000803e3d6000fd5b505050506000600260009054906101000a9004600160a060020a0316600160a060020a031663e9cd80216040518163ffffffff1660e060020a0281526004016020604051808303816000875af115801561290d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129319190613f15565b6004805460c088015160405160e060020a6323b872dd0281529394508493600160a060020a03808616946323b872dd94612971949216928d929101613c73565b600060405180830381600087803b15801561298b57600080fd5b505af1158015610cab573d6000803e3d6000fd5b600154600160a060020a03610100909104163314610d0f5760405160e560020a62461bcd02815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161223b565b612a0a6126a0565b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258335b604051600160a060020a03909116815260200160405180910390a1565b600260005403612aab5760405160e560020a62461bcd02815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161223b565b6002600055565b6000808060001985870985870292508281108382030391505080600003612aec57838281612ae257612ae2613f32565b0492505050612b60565b808411612af857600080fd5b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b600254604080517fe9cd80210000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163e9cd8021916004808301926020929190829003018187875af1158015612bcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bef9190613f15565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301526024820185905291925082918216906340c10f1990604401600060405180830381600087803b158015612c5757600080fd5b505af1158015612c6b573d6000803e3d6000fd5b5050505050505050565b60025460405160e060020a63f9870705028152600160a060020a038086166004830152859260009291169063f987070590602401610180604051808303816000875af1158015612cc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ced9190613a6a565b61012081015160c082015160405160e060020a6323b872dd0281529293509091600160a060020a038516916323b872dd91612d2f919089908990600401613c73565b600060405180830381600087803b158015612d4957600080fd5b505af1158015612d5d573d6000803e3d6000fd5b505082516040517fc5f05a58000000000000000000000000000000000000000000000000000000008152600160a060020a038716935063c5f05a589250610e29918991309190600401613c73565b60025460405160e060020a63f9870705028152600160a060020a038881166004830152600092169063f987070590602401610180604051808303816000875af1158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e209190613a6a565b90506000816101200151905060008890506000889050600081600160a060020a031663313ce5676040518163ffffffff1660e060020a0281526004016020604051808303816000875af1158015612e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9f9190613890565b905081600160a060020a03166323b872dd8a8760c00151600485612ec391906138f4565b612ece90600a613e36565b612ed88b8d613e42565b612ee29190613e42565b6040518463ffffffff1660e060020a028152600401612f0393929190613c73565b600060405180830381600087803b158015612f1d57600080fd5b505af1158015612f31573d6000803e3d6000fd5b50505060c086015160405160e060020a6323b872dd028152600160a060020a03861692506323b872dd91612f6b918c908c90600401613c73565b600060405180830381600087803b158015612f8557600080fd5b505af1158015612f99573d6000803e3d6000fd5b505085516040517fc5f05a58000000000000000000000000000000000000000000000000000000008152600160a060020a038716935063c5f05a589250611ad9918c91309190600401613c73565b60018054600160a060020a0383811661010081810274ffffffffffffffffffffffffffffffffffffffff001985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60025460405160e060020a63f9870705028152600160a060020a038781166004830152600092169063f987070590602401610180604051808303816000875af115801561309f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c39190613a6a565b90506000600260009054906101000a9004600160a060020a0316600160a060020a0316632ed1fd7e6040518163ffffffff1660e060020a0281526004016020604051808303816000875af115801561311f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131439190613b1a565b6101208301518051608085015192935090916000600182600481111561316b5761316b613b5c565b0361317857506000613257565b600282600481111561318c5761318c613b5c565b036132575760006131a284896305f5e100612ab2565b905080866000018181516131b69190613a0d565b905250610100870180518291906131ce908390613a0d565b9052506040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290528c90600160a060020a03821690639dc29fac90604401600060405180830381600087803b15801561323457600080fd5b505af1158015613248573d6000803e3d6000fd5b50505050876101000151925050505b6002546040517ffa5a6f7e000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063fa5a6f7e906132a2908e908a90600401613b9a565b600060405180830381600087803b1580156132bc57600080fd5b505af11580156132d0573d6000803e3d6000fd5b50506002546040517fbacf3ae500000000000000000000000000000000000000000000000000000000815288516004820152600160a060020a03909116925063bacf3ae59150602401600060405180830381600087803b15801561333357600080fd5b505af1158015613347573d6000803e3d6000fd5b50506005546040517f9dc29fac000000000000000000000000000000000000000000000000000000008152600160a060020a038f81166004830152602482018e90529091169250829150639dc29fac90604401600060405180830381600087803b1580156133b457600080fd5b505af11580156133c8573d6000803e3d6000fd5b505050507fa6e56a04e5e97cc0f92c5ac00c5a90f13bf0ea48bbbaecaec6a2178c1aed0c688c8b8b8e8660405161342c959493929190600160a060020a03959095168552602085019390935260408401919091526060830152608082015260a00190565b60405180910390a1505050505050505050505050565b61344a61347b565b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33612a39565b60015460ff16610d0f5760405160e560020a62461bcd02815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161223b565b60405180610120016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b600160a060020a038116811461133857600080fd5b60008060006060848603121561354857600080fd5b83356135538161351e565b925060208401356135638161351e565b929592945050506040919091013590565b60006020828403121561358657600080fd5b8135612b608161351e565b600080604083850312156135a457600080fd5b82356135af8161351e565b946020939093013593505050565b600080600080600060a086880312156135d557600080fd5b85356135e08161351e565b945060208601356135f08161351e565b935060408601356136008161351e565b94979396509394606081013594506080013592915050565b60008060008060008060c0878903121561363157600080fd5b863561363c8161351e565b9550602087013561364c8161351e565b95989597505050506040840135936060810135936080820135935060a0909101359150565b60e060020a634e487b7102600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156136ae576136ae613671565b60405290565b6040805190810167ffffffffffffffff811182821017156136ae576136ae613671565b604051610140810167ffffffffffffffff811182821017156136ae576136ae613671565b6040516080810167ffffffffffffffff811182821017156136ae576136ae613671565b604051601f8201601f1916810167ffffffffffffffff8111828210171561374757613747613671565b604052919050565b600067ffffffffffffffff82111561376957613769613671565b5060209081020190565b8051801515811461378357600080fd5b919050565b6000602080838503121561379b57600080fd5b825167ffffffffffffffff8111156137b257600080fd5b8301601f810185136137c357600080fd5b80516137d66137d18261374f565b61371e565b81815261012091820283018401918482019190888411156137f657600080fd5b938501935b838510156138845780858a0312156138135760008081fd5b61381b61368a565b85518152868601518782015260408087015190820152606080870151908201526080808701519082015260a0808701519082015260c0808701519082015260e08087015190820152610100613871818801613773565b90820152835293840193918501916137fb565b50979650505050505050565b6000602082840312156138a257600080fd5b5051919050565b60e060020a634e487b7102600052603260045260246000fd5b60e060020a634e487b7102600052601160045260246000fd5b6000600182016138ed576138ed6138c2565b5060010190565b81810381811115613907576139076138c2565b92915050565b6000600160a060020a038086168352602081861681850152606060408501528451915081606085015260005b8281101561395557858101820151858201608001528101613939565b50506000608082850101526080601f19601f830116840101915050949350505050565b60006020828403121561398a57600080fd5b612b6082613773565b600061014082019050600160a060020a038416825282516020830152602083015160408301526040830151606083015260608301516080830152608083015160a083015260a083015160c083015260c083015160e083015260e0830151610100818185015280850151151561012085015250509392505050565b80820180821115613907576139076138c2565b600060408284031215613a3257600080fd5b613a3a6136b4565b9050815181526020820151602082015292915050565b80516005811061378357600080fd5b80516137838161351e565b60006101808284031215613a7d57600080fd5b613a856136d7565b8251815260208301516020820152613aa08460408501613a20565b604082015260808301516060820152613abb60a08401613a50565b6080820152613acc60c08401613a5f565b60a0820152613add60e08401613a5f565b60c0820152610100613af0818501613a5f565b60e08301526101208085015182840152613b0e866101408701613a20565b90830152509392505050565b600060208284031215613b2c57600080fd5b6040516020810181811067ffffffffffffffff82111715613b4f57613b4f613671565b6040529151825250919050565b60e060020a634e487b7102600052602160045260246000fd5b60058110613b965760e060020a634e487b7102600052602160045260246000fd5b9052565b60006101a082019050600160a060020a038416825282516020830152602083015160408301526040830151613bdc606084018280518252602090810151910152565b50606083015160a08301526080830151613bf960c0840182613b75565b5060a0830151600160a060020a03811660e08401525060c0830151610100613c2b81850183600160a060020a03169052565b60e08501519150610120613c4981860184600160a060020a03169052565b90850151610140850152840151805161016085015260208101516101808501529050509392505050565b600160a060020a039384168152919092166020820152604081019190915260600190565b60006020808385031215613caa57600080fd5b825167ffffffffffffffff811115613cc157600080fd5b8301601f81018513613cd257600080fd5b8051613ce06137d18261374f565b81815260409182028301840191848201919088841115613cff57600080fd5b938501935b838510156138845780858a031215613d1c5760008081fd5b613d246136b4565b8551613d2f8161351e565b8152613d3c868801613773565b8188015283529384019391850191613d04565b600181815b80851115613d8c578160001904821115613d7057613d706138c2565b80851615613d7d57918102915b60029094049390800290613d54565b509250929050565b600082613da357506001613907565b81613db057506000613907565b8160018114613dc65760028114613dd057613ded565b6001915050613907565b60ff841115613de157613de16138c2565b8360020a915050613907565b5060208310610133831016604e8410600b8410161715613e10575081810a613907565b613e1a8383613d4f565b8060001904821115613e2e57613e2e6138c2565b029392505050565b6000612b608383613d94565b8082028115828204841417613907576139076138c2565b60006020808385031215613e6c57600080fd5b825167ffffffffffffffff811115613e8357600080fd5b8301601f81018513613e9457600080fd5b8051613ea26137d18261374f565b81815260809182028301840191848201919088841115613ec157600080fd5b938501935b838510156138845780858a031215613ede5760008081fd5b613ee66136fb565b855181528686015187820152604080870151908201526060808701519082015283529384019391850191613ec6565b600060208284031215613f2757600080fd5b8151612b608161351e565b60e060020a634e487b7102600052601260045260246000fdfea26469706673582212203dd71afbb46691c111eb1c68a730070016e368e6ddde86d366b4fb2ee60c1c6764736f6c63430008110033000000000000000000000000774263e01b21fe6ee0133e749ec8811135400a1b000000000000000000000000e851906540378f05a49ebfcffe39681f8aab8a1c0000000000000000000000004a47b68bf030d730468bf3365a0115b1cf0909dc
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101775760003560e060020a90048063610be654116100e25780638da5cb5b1161009b578063acc7b76a11610075578063acc7b76a14610304578063bac1520314610317578063f2fde38b1461031f578063f5dfe83a1461033257600080fd5b80638da5cb5b146102c8578063993d10dc146102de578063a37f3d52146102f157600080fd5b8063610be6541461026c57806366d003ac146102745780636e8d82af14610287578063704689771461029a578063715018a6146102ad578063719d5f83146102b557600080fd5b80633e83422e116101345780633e83422e14610202578063439766ce14610215578063456601d71461021d5780635594c630146102305780635b007e08146102435780635c975abb1461025657600080fd5b8063051be3741461017c57806328eeb6e1146101ac5780632d765a3f146101bf57806332917237146101d257806337cf8bf6146101e5578063387fe829146101ef575b600080fd5b60045461018f90600160a060020a031681565b604051600160a060020a0390911681526020015b60405180910390f35b60065461018f90600160a060020a031681565b60035461018f90600160a060020a031681565b60025461018f90600160a060020a031681565b6101ed610345565b005b6101ed6101fd366004613533565b610687565b6101ed610210366004613574565b610cb8565b6101ed610cf7565b6101ed61022b366004613591565b610d11565b6101ed61023e366004613574565b610e63565b6101ed610251366004613574565b610ea2565b60015460ff1660405190151581526020016101a3565b6101ed61133b565b60085461018f90600160a060020a031681565b6101ed610295366004613574565b611351565b6101ed6102a83660046135bd565b611b18565b6101ed611ef4565b60075461018f90600160a060020a031681565b6001546101009004600160a060020a031661018f565b6101ed6102ec366004613618565b611f06565b6101ed6102ff366004613574565b612159565b60055461018f90600160a060020a031681565b6101ed612198565b6101ed61032d366004613574565b6121b0565b6101ed610340366004613591565b61224d565b61034d6126a0565b60025460405160e260020a630aae3b7b028152336004820152600091600160a060020a031690632ab8edec906024016000604051808303816000875af115801561039b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103c39190810190613788565b90506000600260009054906101000a9004600160a060020a0316600160a060020a031663bd4546066040518163ffffffff1660e060020a0281526004016020604051808303816000875af115801561041f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104439190613890565b905060008260008151811061045a5761045a6138a9565b60200260200101516060015190506000805b838110156104d557848181518110610486576104866138a9565b60200260200101516101000151151560001515036104c3578481815181106104b0576104b06138a9565b60200260200101516060015191506104d5565b806104cd816138db565b91505061046c565b50816000036105c057805b838110156105ba57610531338683815181106104fe576104fe6138a9565b60200260200101518760018561051491906138f4565b81518110610524576105246138a9565b60200260200101516126f6565b60025460405160e260020a630aae3b7b028152336004820152600160a060020a0390911690632ab8edec906024016000604051808303816000875af115801561057e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105a69190810190613788565b9450806105b2816138db565b9150506104e0565b50610681565b60006105cc83836138f4565b90505b6105d983856138f4565b81101561067f576105f6338683815181106104fe576104fe6138a9565b60025460405160e260020a630aae3b7b028152336004820152600160a060020a0390911690632ab8edec906024016000604051808303816000875af1158015610643573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261066b9190810190613788565b945080610677816138db565b9150506105cf565b505b50505050565b61068f6126a0565b604080518082018252601581527f7570646174654c617374555761747453746174757300000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb9906106fd9087903090889060040161390d565b6020604051808303816000875af115801561071c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107409190613978565b905060018115151461075157600080fd5b60025460405160e260020a630aae3b7b028152600160a060020a0389811660048301526000921690632ab8edec906024016000604051808303816000875af11580156107a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107c99190810190613788565b60025460405160e260020a630aae3b7b028152600160a060020a038a8116600483015292935060009290911690632ab8edec906024016000604051808303816000875af115801561081e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108469190810190613788565b600454909150600090600160a060020a03908116908b160361086a5750600161086e565b5060005b600254604080517fbd4546060000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163bd454606916004808301926020929190829003018187875af11580156108d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f69190613890565b9050600160a060020a038b1615610a765761090f6134d0565b84516000036109b757602081018a905260e081018a90526001610100820152606081018290526002546040517f147dcb91000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063147dcb9190610980908f908590600401613993565b600060405180830381600087803b15801561099a57600080fd5b505af11580156109ae573d6000803e3d6000fd5b50505050610a74565b84600186516109c691906138f4565b815181106109d6576109d66138a9565b6020026020010151905089816020018181516109f29190613a0d565b90525060e0810180518b9190610a09908390613a0d565b90525060025460405160e460020a6305e669cd028152600160a060020a0390911690635e669cd090610a41908f908590600401613993565b600060405180830381600087803b158015610a5b57600080fd5b505af1158015610a6f573d6000803e3d6000fd5b505050505b505b600160a060020a038a1615610cab57610a8d6134d0565b8351600003610b355760408082018b905260e082018b905260016101008301526060820183905260025490517f147dcb91000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063147dcb9190610afe908e908590600401613993565b600060405180830381600087803b158015610b1857600080fd5b505af1158015610b2c573d6000803e3d6000fd5b50505050610ca9565b8360018551610b4491906138f4565b81518110610b5457610b546138a9565b6020026020010151905082610bc4578981604001818151610b759190613a0d565b90525060e0810180518b9190610b8c908390613a0d565b90525060025460405160e460020a6305e669cd028152600160a060020a0390911690635e669cd090610afe908e908590600401613993565b60025460405160e460020a6305e669cd028152600160a060020a0390911690635e669cd090610bf9908e908590600401613993565b600060405180830381600087803b158015610c1357600080fd5b505af1158015610c27573d6000803e3d6000fd5b50506002546040517fc0deaf4d000000000000000000000000000000000000000000000000000000008152600160a060020a03909116925063c0deaf4d9150610c76908e908590600401613993565b600060405180830381600087803b158015610c9057600080fd5b505af1158015610ca4573d6000803e3d6000fd5b505050505b505b5050505050505050505050565b610cc06126a0565b610cc861299f565b6006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b610cff61299f565b610d076126a0565b610d0f612a02565b565b610d196126a0565b604080518082018252601381527f73657450726f6a6563745369676e6174757265000000000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb990610d879087903090889060040161390d565b6020604051808303816000875af1158015610da6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dca9190613978565b9050600181151514610ddb57600080fd5b6002546040517f42e28ff4000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015260248201889052909116906342e28ff4906044015b600060405180830381600087803b158015610e4357600080fd5b505af1158015610e57573d6000803e3d6000fd5b50505050505050505050565b610e6b6126a0565b610e7361299f565b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b610eaa612a56565b60025460405160e060020a63f9870705028152600160a060020a038084166004830152839260009291169063f987070590602401610180604051808303816000875af1158015610efe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f229190613a6a565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152909150600090600160a060020a038416906370a08231906024016020604051808303816000875af1158015610f87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fab9190613890565b9050600082610120015190506000600260009054906101000a9004600160a060020a0316600160a060020a0316632ed1fd7e6040518163ffffffff1660e060020a0281526004016020604051808303816000875af1158015611011573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110359190613b1a565b610100850151835191925090600061105183620186a084612ab2565b905060006110638783620186a0612ab2565b6040517f79cc679000000000000000000000000000000000000000000000000000000000815233600482015260248101829052909150600160a060020a038a16906379cc679090604401600060405180830381600087803b1580156110c757600080fd5b505af11580156110db573d6000803e3d6000fd5b50506002546040517fb27ef15d000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038e81166024830152909116925063b27ef15d91506044016020604051808303816000875af115801561114a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116e9190613978565b1561121d5786866000018181516111859190613a0d565b90525060208601805188919061119c9083906138f4565b9052506002546040517ffa5a6f7e000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063fa5a6f7e906111ea908d908c90600401613b9a565b600060405180830381600087803b15801561120457600080fd5b505af1158015611218573d6000803e3d6000fd5b505050505b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090600160a060020a038b16906370a08231906024016020604051808303816000875af115801561127f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a39190613890565b60405160e060020a6323b872dd028152909150600160a060020a038b16906323b872dd906112d990339030908690600401613c73565b600060405180830381600087803b1580156112f357600080fd5b505af1158015611307573d6000803e3d6000fd5b505050506113243361131f838c606001516064612ab2565b612b67565b505050505050505050506113386001600055565b50565b61134361299f565b600854600160a060020a0316ff5b604080518082018252600981527f73776170546f6b656e00000000000000000000000000000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb9906113bf9087903090889060040161390d565b6020604051808303816000875af11580156113de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114029190613978565b905060018115151461141357600080fd5b6002546040517f38cac9ba000000000000000000000000000000000000000000000000000000008152600160a060020a03808816600483015287926060929116906338cac9ba906024016000604051808303816000875af115801561147c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114a49190810190613c97565b60025460405160e060020a63f9870705028152600160a060020a038a811660048301529293506000929091169063f987070590602401610180604051808303816000875af11580156114fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151e9190613a6a565b905061154b6040518060800160405280600081526020016000815260200160008152602001600081525090565b60008060005b85518110156119bf576002548651600091600160a060020a03169063b27ef15d90899085908110611584576115846138a9565b6020026020010151600001518f6040518363ffffffff1660e060020a0281526004016115c6929190600160a060020a0392831681529116602082015260400190565b6020604051808303816000875af11580156115e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116099190613978565b9050600088600160a060020a03166370a0823189858151811061162e5761162e6138a9565b60209081029190910101515160405160e060020a63ffffffff8416028152600160a060020a0390911660048201526024016020604051808303816000875af115801561167e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a29190613890565b6004548951919250600160a060020a0316908990859081106116c6576116c66138a9565b602002602001015160000151600160a060020a0316036118e55788600160a060020a03166323b872dd898581518110611701576117016138a9565b60200260200101516000015130846040518463ffffffff1660e060020a02815260040161173093929190613c73565b600060405180830381600087803b15801561174a57600080fd5b505af115801561175e573d6000803e3d6000fd5b505050506000600260009054906101000a9004600160a060020a0316600160a060020a0316632ed1fd7e6040518163ffffffff1660e060020a0281526004016020604051808303816000875af11580156117bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e09190613b1a565b9050818160000151101561184b57805161180a906117fe90846138f4565b89606001516064612ab2565b9550611833898581518110611821576118216138a9565b60200260200101516000015187612b67565b80519450848161184382806138f4565b905250611868565b60009550819450848160000181815161186491906138f4565b9052505b6002546040517fbacf3ae500000000000000000000000000000000000000000000000000000000815282516004820152600160a060020a039091169063bacf3ae590602401600060405180830381600087803b1580156118c757600080fd5b505af11580156118db573d6000803e3d6000fd5b50505050506119aa565b80158015906118f2575081155b156119aa5788600160a060020a03166323b872dd898581518110611918576119186138a9565b60200260200101516000015130846040518463ffffffff1660e060020a02815260040161194793929190613c73565b600060405180830381600087803b15801561196157600080fd5b505af1158015611975573d6000803e3d6000fd5b505050506119aa88848151811061198e5761198e6138a9565b60200260200101516000015161131f838a606001516064612ab2565b505080806119b7906138db565b915050611551565b50602083018290526002546040517f39777ec2000000000000000000000000000000000000000000000000000000008152600160a060020a038d81166004830152839216906339777ec2906024016020604051808303816000875af1158015611a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a509190613890565b611a5a91906138f4565b60408401819052606084018051611a72908390613a0d565b905250600254604080517f03e3155a000000000000000000000000000000000000000000000000000000008152855160048201526020860151602482015290850151604482015260608501516064820152600160a060020a03909116906303e3155a906084015b600060405180830381600087803b158015611af357600080fd5b505af1158015611b07573d6000803e3d6000fd5b505050505050505050505050505050565b604080518082018252600e81527f7057617474735472616e736665720000000000000000000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb990611b869087903090889060040161390d565b6020604051808303816000875af1158015611ba5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc99190613978565b9050600181151514611bda57600080fd5b60025460405160e060020a63f9870705028152600160a060020a038b811660048301528a9260009291169063f987070590602401610180604051808303816000875af1158015611c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c529190613a6a565b905060008161012001519050600083600160a060020a031663313ce5676040518163ffffffff1660e060020a0281526004016020604051808303816000875af1158015611ca3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc79190613890565b9050600260009054906101000a9004600160a060020a0316600160a060020a031663b27ef15d8c8f6040518363ffffffff1660e060020a028152600401611d24929190600160a060020a0392831681529116602082015260400190565b6020604051808303816000875af1158015611d43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d679190613978565b15611e15578982600001818151611d7e91906138f4565b9052506020820180518b9190611d95908390613a0d565b91508181525050600260009054906101000a9004600160a060020a0316600160a060020a031663fa5a6f7e8e856040518363ffffffff1660e060020a028152600401611de2929190613b9a565b600060405180830381600087803b158015611dfc57600080fd5b505af1158015611e10573d6000803e3d6000fd5b505050505b600454600160a060020a03908116908c1603611ed75783600160a060020a031663a9059cbb8460c00151600484611e4c91906138f4565b611e5790600a613e36565b611e618d8f613e42565b611e6b9190613e42565b60405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401600060405180830381600087803b158015611eaf57600080fd5b505af1158015611ec3573d6000803e3d6000fd5b50505050611ed28d8c8c612c75565b611ee5565b611ee58d8d338e8e8e612dab565b50505050505050505050505050565b611efc61299f565b610d0f6000612fe7565b611f0e6126a0565b604080518082018252601581527f65787465726e616c496e766f6963655265706f727400000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb990611f7c9087903090889060040161390d565b6020604051808303816000875af1158015611f9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fbf9190613978565b9050600181151514611fd057600080fd5b60025460405160e060020a63f9870705028152600160a060020a038c81166004830152600092169063f987070590602401610180604051808303816000875af1158015612021573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120459190613a6a565b9050600061205a8a8360200151612710612ab2565b90506000612068828c6138f4565b60405160e060020a6323b872dd0281529091508c90600160a060020a038216906323b872dd906120a090339030908790600401613c73565b600060405180830381600087803b1580156120ba57600080fd5b505af11580156120ce573d6000803e3d6000fd5b505060075460405160e060020a6323b872dd028152600160a060020a0380861694506323b872dd935061210a9233929116908890600401613c73565b600060405180830381600087803b15801561212457600080fd5b505af1158015612138573d6000803e3d6000fd5b505050506121498e8d8d8d8d61304e565b5050505050505050505050505050565b6121616126a0565b61216961299f565b6005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6121a061299f565b6121a86126a0565b610d0f613442565b6121b86126a0565b6121c061299f565b600160a060020a0381166122445760405160e560020a62461bcd02815260206004820152602d60248201527f4f776e61626c653a206e6577206f776e65722063616e6e6f742062652074686560448201527f207a65726f20616464726573730000000000000000000000000000000000000060648201526084015b60405180910390fd5b61133881612fe7565b6122556126a0565b604080518082018252600c81527f656e657267795265706f727400000000000000000000000000000000000000006020820152600654915160e060020a632c460fb90281523392600160a060020a0316906000908290632c460fb9906122c39087903090889060040161390d565b6020604051808303816000875af11580156122e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123069190613978565b905060018115151461231757600080fd5b6005546002546040517fec26e894000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015233602483015292831692600092169063ec26e894906044016020604051808303816000875af115801561238a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ae9190613890565b90508681106124285760405160e560020a62461bcd02815260206004820152603d60248201527f416363756d756c6174656420656e65726779206d75737420626520677265617460448201527f6572207468616e20746865207265676973746572656420656e65726779000000606482015260840161223b565b600061243482896138f4565b6002546040517fec26e894000000000000000000000000000000000000000000000000000000008152600160a060020a038c8116600483015233602483015292935091169063ec26e894906044016020604051808303816000875af11580156124a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c59190613890565b600003612550576002546040517fa6be208b000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063a6be208b90612519908c9033908d90600401613c73565b600060405180830381600087803b15801561253357600080fd5b505af1158015612547573d6000803e3d6000fd5b5050505061264b565b6002546040517fa6be208b000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063a6be208b9061259d908c9033908d90600401613c73565b600060405180830381600087803b1580156125b757600080fd5b505af11580156125cb573d6000803e3d6000fd5b50506040517f40c10f19000000000000000000000000000000000000000000000000000000008152600160a060020a038c8116600483015260248201859052861692506340c10f199150604401600060405180830381600087803b15801561263257600080fd5b505af1158015612646573d6000803e3d6000fd5b505050505b60408051600160a060020a038b168152602081018a90529081018290527f785c4f42ebbc14b75395e9a6c4b77c1306f9a04d9707e9f3daab18e9ca14a4d89060600160405180910390a1505050505050505050565b60015460ff1615610d0f5760405160e560020a62461bcd02815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161223b565b6126fe6126a0565b600254604080517fe32c704e0000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163e32c704e9160048083019286929190829003018183875af1158015612761573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127899190810190613e59565b9050808360600151815181106127a1576127a16138a9565b6020026020010151602001518360800181815250506000818360600151815181106127ce576127ce6138a9565b60200260200101516060015190506127f084600001516402540be40083612ab2565b60a08501819052608085015161280b916402540be400612ab2565b60c0850181905260016101008601526020850151604086015186519192916128339190613a0d565b61283d9190613a0d565b61284791906138f4565b60e085015260025460405160e460020a6305e669cd028152600160a060020a0390911690635e669cd0906128819088908890600401613993565b600060405180830381600087803b15801561289b57600080fd5b505af11580156128af573d6000803e3d6000fd5b505050506000600260009054906101000a9004600160a060020a0316600160a060020a031663e9cd80216040518163ffffffff1660e060020a0281526004016020604051808303816000875af115801561290d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129319190613f15565b6004805460c088015160405160e060020a6323b872dd0281529394508493600160a060020a03808616946323b872dd94612971949216928d929101613c73565b600060405180830381600087803b15801561298b57600080fd5b505af1158015610cab573d6000803e3d6000fd5b600154600160a060020a03610100909104163314610d0f5760405160e560020a62461bcd02815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161223b565b612a0a6126a0565b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258335b604051600160a060020a03909116815260200160405180910390a1565b600260005403612aab5760405160e560020a62461bcd02815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161223b565b6002600055565b6000808060001985870985870292508281108382030391505080600003612aec57838281612ae257612ae2613f32565b0492505050612b60565b808411612af857600080fd5b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b600254604080517fe9cd80210000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163e9cd8021916004808301926020929190829003018187875af1158015612bcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bef9190613f15565b6040517f40c10f19000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301526024820185905291925082918216906340c10f1990604401600060405180830381600087803b158015612c5757600080fd5b505af1158015612c6b573d6000803e3d6000fd5b5050505050505050565b60025460405160e060020a63f9870705028152600160a060020a038086166004830152859260009291169063f987070590602401610180604051808303816000875af1158015612cc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ced9190613a6a565b61012081015160c082015160405160e060020a6323b872dd0281529293509091600160a060020a038516916323b872dd91612d2f919089908990600401613c73565b600060405180830381600087803b158015612d4957600080fd5b505af1158015612d5d573d6000803e3d6000fd5b505082516040517fc5f05a58000000000000000000000000000000000000000000000000000000008152600160a060020a038716935063c5f05a589250610e29918991309190600401613c73565b60025460405160e060020a63f9870705028152600160a060020a038881166004830152600092169063f987070590602401610180604051808303816000875af1158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e209190613a6a565b90506000816101200151905060008890506000889050600081600160a060020a031663313ce5676040518163ffffffff1660e060020a0281526004016020604051808303816000875af1158015612e7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9f9190613890565b905081600160a060020a03166323b872dd8a8760c00151600485612ec391906138f4565b612ece90600a613e36565b612ed88b8d613e42565b612ee29190613e42565b6040518463ffffffff1660e060020a028152600401612f0393929190613c73565b600060405180830381600087803b158015612f1d57600080fd5b505af1158015612f31573d6000803e3d6000fd5b50505060c086015160405160e060020a6323b872dd028152600160a060020a03861692506323b872dd91612f6b918c908c90600401613c73565b600060405180830381600087803b158015612f8557600080fd5b505af1158015612f99573d6000803e3d6000fd5b505085516040517fc5f05a58000000000000000000000000000000000000000000000000000000008152600160a060020a038716935063c5f05a589250611ad9918c91309190600401613c73565b60018054600160a060020a0383811661010081810274ffffffffffffffffffffffffffffffffffffffff001985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60025460405160e060020a63f9870705028152600160a060020a038781166004830152600092169063f987070590602401610180604051808303816000875af115801561309f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c39190613a6a565b90506000600260009054906101000a9004600160a060020a0316600160a060020a0316632ed1fd7e6040518163ffffffff1660e060020a0281526004016020604051808303816000875af115801561311f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131439190613b1a565b6101208301518051608085015192935090916000600182600481111561316b5761316b613b5c565b0361317857506000613257565b600282600481111561318c5761318c613b5c565b036132575760006131a284896305f5e100612ab2565b905080866000018181516131b69190613a0d565b905250610100870180518291906131ce908390613a0d565b9052506040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290528c90600160a060020a03821690639dc29fac90604401600060405180830381600087803b15801561323457600080fd5b505af1158015613248573d6000803e3d6000fd5b50505050876101000151925050505b6002546040517ffa5a6f7e000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063fa5a6f7e906132a2908e908a90600401613b9a565b600060405180830381600087803b1580156132bc57600080fd5b505af11580156132d0573d6000803e3d6000fd5b50506002546040517fbacf3ae500000000000000000000000000000000000000000000000000000000815288516004820152600160a060020a03909116925063bacf3ae59150602401600060405180830381600087803b15801561333357600080fd5b505af1158015613347573d6000803e3d6000fd5b50506005546040517f9dc29fac000000000000000000000000000000000000000000000000000000008152600160a060020a038f81166004830152602482018e90529091169250829150639dc29fac90604401600060405180830381600087803b1580156133b457600080fd5b505af11580156133c8573d6000803e3d6000fd5b505050507fa6e56a04e5e97cc0f92c5ac00c5a90f13bf0ea48bbbaecaec6a2178c1aed0c688c8b8b8e8660405161342c959493929190600160a060020a03959095168552602085019390935260408401919091526060830152608082015260a00190565b60405180910390a1505050505050505050505050565b61344a61347b565b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33612a39565b60015460ff16610d0f5760405160e560020a62461bcd02815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161223b565b60405180610120016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b600160a060020a038116811461133857600080fd5b60008060006060848603121561354857600080fd5b83356135538161351e565b925060208401356135638161351e565b929592945050506040919091013590565b60006020828403121561358657600080fd5b8135612b608161351e565b600080604083850312156135a457600080fd5b82356135af8161351e565b946020939093013593505050565b600080600080600060a086880312156135d557600080fd5b85356135e08161351e565b945060208601356135f08161351e565b935060408601356136008161351e565b94979396509394606081013594506080013592915050565b60008060008060008060c0878903121561363157600080fd5b863561363c8161351e565b9550602087013561364c8161351e565b95989597505050506040840135936060810135936080820135935060a0909101359150565b60e060020a634e487b7102600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156136ae576136ae613671565b60405290565b6040805190810167ffffffffffffffff811182821017156136ae576136ae613671565b604051610140810167ffffffffffffffff811182821017156136ae576136ae613671565b6040516080810167ffffffffffffffff811182821017156136ae576136ae613671565b604051601f8201601f1916810167ffffffffffffffff8111828210171561374757613747613671565b604052919050565b600067ffffffffffffffff82111561376957613769613671565b5060209081020190565b8051801515811461378357600080fd5b919050565b6000602080838503121561379b57600080fd5b825167ffffffffffffffff8111156137b257600080fd5b8301601f810185136137c357600080fd5b80516137d66137d18261374f565b61371e565b81815261012091820283018401918482019190888411156137f657600080fd5b938501935b838510156138845780858a0312156138135760008081fd5b61381b61368a565b85518152868601518782015260408087015190820152606080870151908201526080808701519082015260a0808701519082015260c0808701519082015260e08087015190820152610100613871818801613773565b90820152835293840193918501916137fb565b50979650505050505050565b6000602082840312156138a257600080fd5b5051919050565b60e060020a634e487b7102600052603260045260246000fd5b60e060020a634e487b7102600052601160045260246000fd5b6000600182016138ed576138ed6138c2565b5060010190565b81810381811115613907576139076138c2565b92915050565b6000600160a060020a038086168352602081861681850152606060408501528451915081606085015260005b8281101561395557858101820151858201608001528101613939565b50506000608082850101526080601f19601f830116840101915050949350505050565b60006020828403121561398a57600080fd5b612b6082613773565b600061014082019050600160a060020a038416825282516020830152602083015160408301526040830151606083015260608301516080830152608083015160a083015260a083015160c083015260c083015160e083015260e0830151610100818185015280850151151561012085015250509392505050565b80820180821115613907576139076138c2565b600060408284031215613a3257600080fd5b613a3a6136b4565b9050815181526020820151602082015292915050565b80516005811061378357600080fd5b80516137838161351e565b60006101808284031215613a7d57600080fd5b613a856136d7565b8251815260208301516020820152613aa08460408501613a20565b604082015260808301516060820152613abb60a08401613a50565b6080820152613acc60c08401613a5f565b60a0820152613add60e08401613a5f565b60c0820152610100613af0818501613a5f565b60e08301526101208085015182840152613b0e866101408701613a20565b90830152509392505050565b600060208284031215613b2c57600080fd5b6040516020810181811067ffffffffffffffff82111715613b4f57613b4f613671565b6040529151825250919050565b60e060020a634e487b7102600052602160045260246000fd5b60058110613b965760e060020a634e487b7102600052602160045260246000fd5b9052565b60006101a082019050600160a060020a038416825282516020830152602083015160408301526040830151613bdc606084018280518252602090810151910152565b50606083015160a08301526080830151613bf960c0840182613b75565b5060a0830151600160a060020a03811660e08401525060c0830151610100613c2b81850183600160a060020a03169052565b60e08501519150610120613c4981860184600160a060020a03169052565b90850151610140850152840151805161016085015260208101516101808501529050509392505050565b600160a060020a039384168152919092166020820152604081019190915260600190565b60006020808385031215613caa57600080fd5b825167ffffffffffffffff811115613cc157600080fd5b8301601f81018513613cd257600080fd5b8051613ce06137d18261374f565b81815260409182028301840191848201919088841115613cff57600080fd5b938501935b838510156138845780858a031215613d1c5760008081fd5b613d246136b4565b8551613d2f8161351e565b8152613d3c868801613773565b8188015283529384019391850191613d04565b600181815b80851115613d8c578160001904821115613d7057613d706138c2565b80851615613d7d57918102915b60029094049390800290613d54565b509250929050565b600082613da357506001613907565b81613db057506000613907565b8160018114613dc65760028114613dd057613ded565b6001915050613907565b60ff841115613de157613de16138c2565b8360020a915050613907565b5060208310610133831016604e8410600b8410161715613e10575081810a613907565b613e1a8383613d4f565b8060001904821115613e2e57613e2e6138c2565b029392505050565b6000612b608383613d94565b8082028115828204841417613907576139076138c2565b60006020808385031215613e6c57600080fd5b825167ffffffffffffffff811115613e8357600080fd5b8301601f81018513613e9457600080fd5b8051613ea26137d18261374f565b81815260809182028301840191848201919088841115613ec157600080fd5b938501935b838510156138845780858a031215613ede5760008081fd5b613ee66136fb565b855181528686015187820152604080870151908201526060808701519082015283529384019391850191613ec6565b600060208284031215613f2757600080fd5b8151612b608161351e565b60e060020a634e487b7102600052601260045260246000fdfea26469706673582212203dd71afbb46691c111eb1c68a730070016e368e6ddde86d366b4fb2ee60c1c6764736f6c63430008110033