Overview
WEMIX Balance
WEMIX Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Pause | 39319002 | 461 days ago | IN | 0 WEMIX | 0.0049236 |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
CrossBridgeOrigin
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IEXBridge.sol"; import { CrossBridgeBase } from "CrossBridgeBase.sol"; import { Sig } from "UniversalTypes.sol"; import { SlotAdminable } from "SlotAdminable.sol"; import { INCPStaking } from "INCPStaking.sol"; import "IWithdrawalNFT.sol"; contract CrossBridgeOrigin is ICrossBridgeOrigin, CrossBridgeBase { constructor( address owner, StakingInfo memory _stakingInfo ) { initCrossBridgeOrigin( owner, _stakingInfo ); } function initCrossBridgeOrigin( address owner, StakingInfo memory _stakingInfo ) public override initializer { _transferOwnership(msg.sender); setStakingInfo(_stakingInfo); _transferOwnership(owner); } receive() whenNotPaused external payable override { } function toRemote(address account) whenNotPaused public payable override { if(account == address(0)) account = msg.sender; _stake(msg.value); ConfigSnapshot memory snapshot = _getBridgeSnapshot(); snapshot.localAsset = _processBridgeTransfer(snapshot, ToRemoteStartMessageInfo(account, msg.value), true); _updateAssetInfo(snapshot.localAsset); _claimReward(stakingInfo); } function requestReceive( uint64 srcNonce, ToOriginMessageInfo memory msgBridge, Sig[] memory sigs ) whenNotPaused external override returns(uint256[] memory withdrawalIds) { require(!filterSrcNonce[srcNonce], "src nonce"); filterSrcNonce[srcNonce] = true; ConfigSnapshot memory snapshot = _getBridgeSnapshot(); snapshot.localAsset = _processBridgeReceive(snapshot, srcNonce, msgBridge, sigs); withdrawalIds = _requestUnstake(msgBridge); _updateAssetInfo(snapshot.localAsset); _claimReward(stakingInfo); } function completeReceive(uint256 ncpId, uint256 withdrawalId) whenNotPaused external override { _completeUnstake(ncpId, withdrawalId); } function claimReward() whenNotPaused public override { _claimReward(stakingInfo); } function sync() whenNotPaused external payable override { ConfigSnapshot memory snapshot = _getBridgeSnapshot(); address _syncAccount = syncAccount; require(msg.sender == _syncAccount, "sync"); _stake(msg.value); snapshot.localAsset.bridgeTotalLocked += uint128(msg.value); snapshot.localAsset.bridgeTotalSyncStaking += uint128(msg.value); _updateAssetInfo(snapshot.localAsset); uint64 _localNonce = _useLocalNonce(); emit Sync(_localNonce, _syncAccount, msg.value); } function _processBridgeTransfer( ConfigSnapshot memory snapshot, ToRemoteStartMessageInfo memory msgBridge, bool applyingFee ) internal returns(AssetInfo memory) { uint256 feeAmount; _checkBridgeTransferAmount(msgBridge.amount, snapshot.bridgeAmountConfig); if (applyingFee) { feeAmount = _calcFee(msgBridge.amount, snapshot.feeConfig); require(msgBridge.amount > feeAmount, "fee amount"); unchecked{ msgBridge.amount -= feeAmount; } } snapshot.localAsset.bridgeTotalLocked += uint128(msgBridge.amount); uint64 _localNonce = _useLocalNonce(); emit ToRemote(_localNonce, msgBridge.account, msgBridge.amount, feeAmount); return snapshot.localAsset; } function _stake(uint256 amount) internal { StakingInfo memory _stakingInfo = stakingInfo; INCPStaking staking = INCPStaking(_stakingInfo.stake_contract); (uint8[] memory ncpIds, uint128[] memory tmp) = _determineStakePid(_stakingInfo, uint128(amount)); for(uint256 i; i<ncpIds.length; i++) { staking.deposit{value: tmp[i]}( ncpIds[i], //ncpId default tmp[i], //amount payable(address(this)), //payable to false, //claimReward false //comp ); } } function _processBridgeReceive( ConfigSnapshot memory snapshot, uint64 srcNonce, ToOriginMessageInfo memory msgBridge, Sig[] memory sigs ) internal returns(AssetInfo memory) { _verifyToOriginMessage(srcNonce, msgBridge, sigs); snapshot.localAsset.bridgeTotalLocked -= uint128(msgBridge.amount); emit ToOriginReceived(srcNonce, msgBridge.account, msgBridge.amount); return snapshot.localAsset; } function _requestUnstake(ToOriginMessageInfo memory msgBridge) internal returns (uint256[] memory withdrawalIds) { StakingInfo memory _stakingInfo = stakingInfo; INCPStaking staking = INCPStaking(_stakingInfo.stake_contract); (uint8[] memory ncpIds, uint128[] memory tmp) = _determineUnstakePid(_stakingInfo, uint128(msgBridge.amount)); uint256 tmpAmount; for(uint256 i; i<ncpIds.length; i++) { tmpAmount = tmp[i]; tmp[i] = uint128(staking.withdrawRequest( ncpIds[i], // ncpId default ncpIds[i], // toPid default tmpAmount, // amount payable(address(this)), // to false, // claimReward false // comp )); require(filterWithdrawalId[tmp[i]] == address(0), "withdrawalId"); filterWithdrawalId[tmp[i]] = msgBridge.account; emit ReceivePending(msgBridge.account, ncpIds[i], tmp[i], tmpAmount); } // optimize: array type change assembly { withdrawalIds := tmp } } function _completeUnstake(uint256 ncpId, uint256 withdrawalId) internal { address account = filterWithdrawalId[withdrawalId]; require(account != address(0), "withdrawalId filter"); delete filterWithdrawalId[withdrawalId]; INCPStaking staking = INCPStaking(stakingInfo.stake_contract); uint256 amount = staking.withdrawalNFT().getWithdrawalRequestInfo(withdrawalId).amount; uint256 beforeBalance = address(this).balance; staking.withdraw( ncpId, // ncpId default withdrawalId, // withdrawal Id payable(account) // user address ); require(address(this).balance - beforeBalance == amount, "withdraw amount"); _trySendValueCatchFail(payable(account), amount); emit ReceiveComplete(account, ncpId, withdrawalId); } function _determineStakePid( StakingInfo memory _stakingInfo, uint128 amount ) internal pure returns ( uint8[] memory ncpIds, uint128[] memory amounts ) { require(_stakingInfo.ncpIds.length == 1, "default ncpId"); ncpIds = _stakingInfo.ncpIds; amounts = new uint128[](1); amounts[0] = amount; } function _determineUnstakePid( StakingInfo memory _stakingInfo, uint128 amount ) internal pure returns ( uint8[] memory ncpIds, uint128[] memory amounts ) { return _determineStakePid(_stakingInfo, amount); } function _claimReward(StakingInfo memory _stakingInfo) internal returns (uint256 reward_amount) { address _syncAccount = syncAccount; require(_syncAccount != address(0), "sync zero"); INCPStaking staking = INCPStaking(_stakingInfo.stake_contract); reward_amount = _syncAccount.balance; for(uint256 i; i<_stakingInfo.ncpIds.length; i++) { staking.claim(_stakingInfo.ncpIds[i], _syncAccount); } // TODO: emit reward reward_amount = _syncAccount.balance - reward_amount; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { Sig } from "UniversalTypes.sol"; import { INCPStaking } from "INCPStaking.sol"; import { IEcoERC20 } from "IEcoERC20.sol"; struct ConfigSnapshot { FeeConfig feeConfig; BridgeAmountConfig bridgeAmountConfig; AssetInfo localAsset; } struct StakingInfo { address stake_contract; uint8[] ncpIds; } struct FeeConfig { uint256 min; uint256 max; uint32 rate; } struct BridgeAmountConfig { uint256 min; uint256 max; uint128 toOriginNativeFee; uint128 toRemoteNativeSwapAmount; } struct AssetInfo { uint128 bridgeTotalLocked; uint128 bridgeTotalSyncStaking; } struct BridgeContractInfo { uint32 chainId; address bridge; uint64 nonce; } struct ToOriginMessageInfo { address account; uint256 amount; } struct ToRemoteStartMessageInfo { address account; uint256 amount; } struct ToRemoteMessageInfo { address account; uint256 amount; uint256 amountForNativeAlloc; } enum BrigeMessegeType { NoneType, ToRemote, ToOrigin, Sync } interface IEXBridgeBase { event FailSendValue(address indexed to, uint256 amount); function rateBase() external pure returns (uint32); function getSrcBridgeContractInfo() external view returns (BridgeContractInfo memory); function getStakingInfo() external view returns (StakingInfo memory); function getFeeConfig() external view returns (FeeConfig memory); function getBridgeAmountConfig() external view returns (BridgeAmountConfig memory); function getLocalAsset() external view returns (AssetInfo memory); function localNonce() external view returns (uint64); function filterSrcNonce(uint256 sourceNonce) external returns (bool filtered); function filterWithdrawalId(uint256 withdrawalId) external returns (address account); function setFeeAccount(address _feeAccount) external; function setSyncAccount(address _syncAccount) external; function setBridgePairInfo(BridgeContractInfo memory _pairBridgeInfo) external; function setFeeConfig(FeeConfig memory _feeConfig) external; function setStakingInfo(StakingInfo memory _stakingInfo) external; function setBridgeAmountConfig(BridgeAmountConfig memory _bridgeAmountConfig) external; function calcBridgeTransferAmount(uint256 amount) external view returns (uint256 transferAmount, uint256 feeAmount); function calcFee(uint256 amount) external view returns (uint256 feeAmount); function recoversToOriginMessage( uint64 nonce, ToOriginMessageInfo memory msgToOrigin, Sig[] memory sigs ) external view returns (address[] memory signers); function recoversToRemoteMessage( uint64 nonce, ToRemoteMessageInfo memory msgToRemote, Sig[] memory sigs ) external view returns (address[] memory signers); function recoversSyncMessage( uint64 nonce, uint256 amount, Sig[] memory sigs ) external view returns (address[] memory signers); } interface ICrossBridgeOrigin is IEXBridgeBase { event ToRemote(uint64 indexed localNonce, address indexed account, uint256 amount, uint256 feeAmount); event ToOriginReceived(uint64 indexed srcNonce, address indexed account, uint256 amount); event Sync(uint64 indexed localNonce, address indexed account, uint256 amount); event ReceivePending(address indexed account, uint256 indexed ncpId, uint256 nftId, uint256 amount); event ReceiveComplete(address indexed account, uint256 indexed ncpId, uint256 indexed nftId); receive() external payable; function initCrossBridgeOrigin(address owner, StakingInfo memory _stakingInfo) external; function toRemote(address account) external payable; function requestReceive( uint64 srcNonce, ToOriginMessageInfo memory msgBridge, Sig[] memory sigs ) external returns (uint256[] memory withdrawalIds); function completeReceive(uint256 ncpId, uint256 withdrawalId) external; function claimReward() external; function sync() external payable; } interface ICrossBridgeRemote is IEXBridgeBase { event ToOrigin(uint64 indexed localNonce, address indexed account, uint256 amount, uint256 feeAmount); event ToRemoteReceived(uint64 indexed srcNonce, address indexed account, uint256 amount); event SyncReceived(uint64 indexed localNonce, address indexed account, uint256 amount); event Deposit(address indexed account, uint256 amount); event Withdrawal(address indexed account, uint256 amount); receive() external payable; function initCrossBridgeRemote(address owner, IEcoERC20 _token) external; function setRemoteToken(IEcoERC20 _remoteToken) external; function getRemoteToken() external view returns (IEcoERC20); function deposit() external payable; function withdraw(uint256 amount) external; function toOrigin(address to, uint256 amount) external payable; function completeReceive(uint64 srcNonce, ToRemoteMessageInfo memory msgBridge, Sig[] memory sigs) external; function completeSync(uint64 srcNonce, uint256 amount, Sig[] memory sigs) external; } interface IEXOriginStakingBase { function wonderStaking() external view returns (INCPStaking); function syncAccount() external view returns (address payable); function initEXOriginStaking(address owner, INCPStaking _wonderStaking, address payable _syncAccount) external; receive() external payable; function setWonderStaking(INCPStaking _wonderStaking) external; function setSyncAccount(address payable _syncAccount) external; } interface IEXOriginStaking is IEXOriginStakingBase { function stake(uint256 ncpId) external payable; function claimReward(uint256 ncpId) external; function unstakeRequest(uint256 ncpId, uint256 amount, address payable account) external returns (uint256 tokenId); function unstake(uint256 ncpId, uint256 tokenId, address payable account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; struct Sig { uint8 v; bytes32 r; bytes32 s; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IERC20.sol"; import "IRewarder.sol"; import "IWithdrawalNFT.sol"; /// @author @seunghwalee interface INCPStaking { /* =========== STATE VARIABLES ===========*/ function withdrawalNFT() external returns(IWithdrawalNFT); /** * @notice Info of each WEMIX 3.0 Staking user. * `amount` LP token amount the user has provided. * `rewardDebt` The amount of reward entitled to the user. * `pendingReward` The amount of rewards(lp + mp) the user will receive. * `pendingAmountReward` The amount of rewards(lp) the user will receive. * `withdrawRequest` The withdrawal request info from user. */ struct UserInfo { uint256 amount; uint256 rewardDebt; uint256 pendingReward; uint256 pendingAmountReward; uint256 lastRewardClaimed; } /** * @notice Info of each WEMIX 3.0 Staking user. * `staked` Current user's mp amount. * `lastMPUpdatedTime` The amount of reward entitled to the user. */ struct UserMPInfo { uint256 staked; uint256 lastMPUpdatedTime; } /** * @notice Info of each WEMIX 3.0 Staking user. * `staked` Current user's mp amount. * `lastMPUpdatedTime` The amount of reward entitled to the user. */ struct FeeRatioRequestInfo { uint256 ratio; uint256 requestBlockNumber; } /** * @notice Info of each WEMIX 3.0 Staking pool. * `accRewardPerShare` Accumulated reward per share. * `accMPPerShare` Accumulated mp per share. * `lastRewardBlock` Last block number that Rewards distribution occurs. * `totalDeposit` The amount of total deposit lp token. * `totalMP` The amount of total deposit mp. * `rewardToken` The address of the reward token. * `isInputNative` True if lp token is native coin. * `isRewardNative` True if reward token is native coin. * `activatedMP` True if mp is used. * `lock` True in case of emergency. * `path` The Path to be used when running compound function. * `breaker` The address of breaker. * `breakerSetter` The address of breakerSetter. * `feeRatio` The withdrawal fee ratio. */ struct PoolInfo { address ncp; bytes name; uint256 accRewardPerShare; uint256 accMPPerShare; uint256 lastRewardBlock; uint256 totalDeposit; uint256 totalMP; uint256 unbondTime; uint256 totalRequestedWithdrawal; uint256 feeRatio; bool activatedMP; bool lock; address breaker; address breakerSetter; address feeCollector; uint256 totalDepositors; } function version() external view returns (uint256); /** * @notice Add a new LP to the pool. Can only be called by the owner. * DO NOT add the same LP token more than once. Rewards will be messed up if you do. * @param _ncp Address of ncp. * @param _feeCollector Address of the fee collector. * @param _rewarder Address of the rewarder delegate. * @param _activatedMP True if mp is used. * @param _lock True in case of emergency. * @param _breaker The address of breaker. * @param _breakerSetter The address of breakerSetter. * @param _feeRatio The withdrawal fee ratio. */ function add( address _ncp, address _feeCollector, IRewarder _rewarder, bool _activatedMP, bool _lock, address _breaker, address _breakerSetter, uint256 _feeRatio, uint256 _initValue ) external; /* =========== SET FUNCTIONS =========== */ /** * @notice Changed fee collector. only rewarder owner can change it's fee collector. * @param pid The index of the pool. See `poolInfo`. * @param _feeCollector Address of the fee collector. */ function setFeeCollector( uint256 pid, address _feeCollector ) external; function setPoolBreaker(uint256 pid, address _breaker) external; function setPoolBreakerSetter(uint256 pid, address _breakerSetter) external; function lockContract(uint256 pid) external; function unlockContract(uint256 pid) external; /** * @notice View function to see pending reward token on frontend. * @param pid The index of the pool. See `poolInfo`. * @param _user Address of user. * @return pending reward for a given user. */ function pendingReward( uint256 pid, address _user ) external view returns (uint256 pending); /** * @notice View function to see pending reward token on frontend. * @param pid The index of the pool. See `poolInfo`. * @param _user Address of user. * @return totalPendingReward total reward for a given user. * @return lpPendingReward lp reward for a given user. * @return mpPendingReward mp reward for a given user. */ function pendingRewardInfo( uint256 pid, address _user ) external view returns ( uint256 totalPendingReward, uint256 lpPendingReward, uint256 mpPendingReward ); /** * @notice View function to see pending reward token on frontend. * @param pid The index of the pool. See `poolInfo`. * @param account Address of user. * @return mpAmount The amount of mp to receive when updateMP function is executed. */ function pendingMP( uint256 pid, address account ) external view returns (uint256 mpAmount); /** * @notice The number of WEMIX 3.0 Staking pools. * @return pools Pool lengths. */ function poolLength() external view returns (uint256 pools); /** * @notice View function to see user staking info. * @param pid The index of the pool. See `poolInfo`. * @param account Address of user. * @return info user staking info */ function getUserInfo( uint256 pid, address account ) external view returns (UserInfo memory info); /** * @notice View function to see user multiplier info. * @param pid The index of the pool. See `poolInfo`. * @param account Address of user. * @return info user multiplier point info */ function getUserMPInfo( uint256 pid, address account ) external view returns (UserMPInfo memory info); /** * @notice View function to see staking pool info. * @param pid The index of the pool. See `poolInfo`. * @return info staking pool info */ function getPoolInfo( uint256 pid ) external view returns (PoolInfo memory info); /** * @notice View function to see staking token address. * @param pid The index of the pool. See `poolInfo`. * @return addr staking pool rewarder address */ function getRewarder(uint256 pid) external view returns (address addr); /** * @notice Update reward variables for all pools. Be careful of gas spending! * @param pids Pool IDs of all to be updated. Make sure to update all active pools. */ function massUpdatePools(uint256[] calldata pids) external; /** * @notice Update reward variables of the given pool. * @param pid The index of the pool. See `poolInfo`. * @return pool Returns the pool that was updated. */ function updatePool( uint256 pid ) external payable returns (PoolInfo memory pool); /** * @notice Deposit LP tokens to WEMIX 3.0 Staking for reward. * @param pid The index of the pool. See `poolInfo`. * @param amount LP token amount to deposit. * @param to The receiver of `amount` deposit benefit. */ function deposit( uint256 pid, uint256 amount, address payable to, bool claimReward, bool comp ) external payable; /** * @notice Withdraw LP tokens from WEMIX 3.0 Staking. * @param pid The index of the pool. See `poolInfo`. * @param tokenId withdrawal tokenid. * @param to Receiver of the LP tokens. */ function withdraw( uint256 pid, uint256 tokenId, address payable to ) external; /** * @notice Withdraw LP tokens from WEMIX 3.0 Staking. * @param pid The index of the pool. See `poolInfo`. * @param toPid The index of the pool whose staking will change. * @param amount LP token amount to withdraw. * @param to Receiver of the LP tokens. */ function withdrawRequest( uint256 pid, uint256 toPid, uint256 amount, address payable to, bool claimReward, bool comp ) external returns (uint256); /** * @notice Harvest proceeds for transaction sender to `to`. * @param pid The index of the pool. See `poolInfo`. * @param to Receiver of rewards. */ function claim(uint256 pid, address to) external; /** * @notice Compound proceeds for transaction sender to `to`. * @param pid The index of the pool. See `poolInfo`. * @param to Receiver of rewards. */ function compound(uint256 pid, address to) external; function computePendingAmountReward( uint256 pendingReward, uint256 lpAmount, uint256 mpAmount ) external pure returns (uint256); function ncpDeposit( uint256 amount, address payable to ) external payable; function ncpWithdraw( uint256 amount, address payable to ) external payable; function getPlatformFeeRatio() external view returns (uint256); /** * @notice View function to see staking pool info. * @param pid The index of the pool. See _poolInfo. * @return info staking pool info */ function getFeeRequestInfo( uint256 pid ) external view returns (FeeRatioRequestInfo memory info); // function massMigration(uint256[] calldata pids, address to) external; // function migration(uint256 pid, address to) external; /* ========== EVENTS ========== */ event Deposit( address indexed user, uint256 indexed pid, uint256 amount, address indexed to, uint256 rewardAmount ); event NCPDeposit( address indexed user, uint256 indexed pid, bytes name, address indexed ncp, uint256 amount, address to, uint256 rewardAmount ); event WithdrawRequest( address indexed user, uint256 indexed pid, bytes name, address indexed ncp, uint256 amount, address to, uint256 rewardAmount ); event Withdraw( address indexed user, uint256 indexed pid, uint256 amount, address indexed to ); event NCPWithdraw( address indexed user, uint256 indexed pid, bytes name, address indexed ncp, uint256 amount, address to ); event Harvest(address indexed user, uint256 indexed pid, uint256 amount); event NCPHarvest( address indexed user, uint256 indexed pid, bytes name, address indexed ncp, uint256 amount, address to ); event LogPoolAddition( uint256 indexed pid, IRewarder indexed rewarder, bool lock, address breaker, address breakerSetter, uint256 feeRatio ); event LogSetPool( uint256 indexed pid, IRewarder indexed rewarder, address feeCollector, uint256 feeRatio ); event LogOnReward(address indexed to, uint256 amount); event SetPoolBreaker(uint256 pid, address breaker); event SetPoolBreakerSetter(uint256 pid, address breakerSetter); event LockContract(uint256 pid); event UnlockContract(uint256 pid); event LogUpdatePool( uint256 indexed pid, uint256 lastRewardBlock, uint256 lpSupply, uint256 accRewardPerShare ); event SetMultiplierPointBasis(uint256 prev, uint256 curr); event SetUnbondTime(uint256 time); event SetFeeCollector(address prev, address curr); event SetRewardFeeRatioRequest( uint256 pid, uint256 prev, uint256 curr, uint256 executeBlockNumber ); event SetRewardFeeRatio(uint256 pid, uint256 prev, uint256 curr); event SetPlatformFeeRatio(uint256 prev, uint256 curr); event SetWithdrawalNFT(address prev, address curr); event SetRewardFeeRatioRequestDelay(uint256 prev, uint256 curr); ///TODO updateMP event // result updated mp value and pendingReward }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IRewarder { function onReward( address payable to, uint256 amount, address payable feeCollector, uint256 fee, address payable platform, uint256 platformFee ) external returns(uint256); function update() external returns(uint256); function getLastReward() external view returns(uint256); function checkRewarder(address _rewarder) external view returns (uint256); function checkOwner(address _owner) external view returns (bool); event LogOnReward(address to, uint256 amount, address feeCollector, uint256 fee, address platform, uint256 platformFee); event SetRewarder(address rewarder, bool isRewarder); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "ERC721Upgradeable.sol"; interface IWithdrawalNFT is IERC721Upgradeable { /** * @notice Info of users withdraw info. * `amount` The amount of withdrawal request. * `requestTime` The time the withdrawal request came in. * `claimableTime` The time of claimable withdrawal. */ struct WithdrawalRequestInfo { uint256 tokenid; uint256 pid; uint256 toPid; uint256 amount; uint256 requestTime; uint256 claimableTime; address drawer; } function mint( address to, uint256 pid, uint256 toPid, uint256 amount, uint256 unbondTime ) external returns (uint256); function burn(address from, uint256 tokenId) external; function getUserTokenList( address user ) external view returns (uint256[] memory); function getWithdrawalRequestInfo( uint256 tokenId ) external view returns (WithdrawalRequestInfo memory); function getWithdrawableTokenList( address user ) external view returns (uint256[] memory); function getFirstWithdrawableToken(uint256 pid, address user) external view returns(uint256); function getWithdrawableTokenListWithPid(uint256 pid, address user) external view returns(uint256[] memory); event Mint(uint256 tokenId, uint256 pid, uint256 toPid, uint256 amount, uint256 mintTime, uint256 unbondTime, address drawer); event Burn(address from, uint256 tokenId); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "IERC721Upgradeable.sol"; import "IERC721ReceiverUpgradeable.sol"; import "IERC721MetadataUpgradeable.sol"; import "AddressUpgradeable.sol"; import "ContextUpgradeable.sol"; import "StringsUpgradeable.sol"; import "ERC165Upgradeable.sol"; import {Initializable} from "Initializable.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable { using AddressUpgradeable for address; using StringsUpgradeable for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC721Upgradeable).interfaceId || interfaceId == type(IERC721MetadataUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721Upgradeable.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721Upgradeable.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721Upgradeable.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721Upgradeable.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721ReceiverUpgradeable.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[44] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "MathUpgradeable.sol"; import "SignedMathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { 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) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 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 256, 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 << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "IERC165Upgradeable.sol"; import {Initializable} from "Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import { IERC20 } from "IERC20.sol"; import { IERC20Metadata } from "IERC20Metadata.sol"; import { IAdminable } from "ISlotAdminable.sol"; interface IWETH is IERC20, IERC20Metadata { function deposit() external payable; function withdraw(uint) external; } interface IERC20Burnable is IERC20, IERC20Metadata { function burn(uint256 amount) external; function burnFrom(address account, uint256 amount) external; } interface IERC20Mintable is IAdminable, IERC20, IERC20Metadata { function initERC20Mintable(address owner) external; function mint(address to, uint256 amount) external; } interface IERC20MetadataInitializable is IAdminable, IERC20, IERC20Metadata { function initERC20MetadataInitializable(string memory name_, string memory symbol_, uint8 decimals_) external; } interface IEcoERC20 is IERC20Mintable, IERC20Burnable, IERC20MetadataInitializable {} interface IEcoERC20Pausable is IEcoERC20 {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAdminable } from "SlotAdminable.sol";
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { Initializable } from "Initializable.sol"; import { Ownable } from "Ownable.sol"; import { StorageSlot } from "StorageSlot.sol"; import { Multicall } from "Multicall.sol"; import { SlotPausable } from "SlotPausable.sol"; interface IAdminable { event AdminshipTransferred(address indexed previousAdmin, address indexed newAdmin); error Adminship(); function call( address to, uint256 value, bytes calldata data ) external payable returns (bool success, bytes memory returnData); function is_admin(address admin) external returns (bool); function grant_admin(address admin) external; function revoke_admin(address admin) external; function renounceAdminship() external; function pause() external ; function unpause() external ; } contract SlotAdminable is IAdminable, Initializable, Ownable, SlotPausable, Multicall { // This is the keccak-256 hash of "adminable.address.mapping.slot" subtracted by 1 bytes32 private constant _ADMIN_MAP_SLOT = 0xd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b; modifier onlyAuthorized() { if (!(is_admin(_msgSender()) || _msgSender() == owner())) revert Adminship(); _; } // Ownable Override, remove admin ship function _transferOwnership(address newOwner) internal virtual override { address oldOwner = owner(); if (is_admin(oldOwner)) _transferAdminship(oldOwner, address(0)); super._transferOwnership(newOwner); } function call( address to, uint256 value, bytes calldata data ) external payable override onlyOwner returns (bool success, bytes memory returnData) { return to.call{ value: value }(data); } function is_admin(address admin) public view returns (bool) { return get_admin_slot(admin).value; } function grant_admin(address admin) public onlyOwner { _transferAdminship(address(0), admin); } function revoke_admin(address admin) public onlyOwner { _transferAdminship(admin, address(0)); } function renounceAdminship() public { _transferAdminship(_msgSender(), address(0)); } function pause() external onlyAuthorized { _pause(); } function unpause() external onlyAuthorized { _unpause(); } function get_admin_slot(address admin) internal pure returns (StorageSlot.BooleanSlot storage) { // evm mapping slot: keccak256( abi.encode(<KEY>, <MAPPING_POSITION>) ) return StorageSlot.getBooleanSlot(keccak256(abi.encode(admin, _ADMIN_MAP_SLOT))); } function _set_admin_flag(address admin, bool flag) internal { if (admin != address(0)) { StorageSlot.BooleanSlot storage admin_slot = get_admin_slot(admin); if (admin_slot.value == flag) revert Adminship(); admin_slot.value = flag; } } function _transferAdminship(address old_admin, address new_admin) internal { _set_admin_flag(old_admin, false); _set_admin_flag(new_admin, true); emit AdminshipTransferred(old_admin, new_admin); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "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. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.5) (utils/Multicall.sol) pragma solidity ^0.8.0; import "Address.sol"; import "Context.sol"; /** * @dev Provides a function to batch together multiple calls in a single external call. * * Consider any assumption about calldata validation performed by the sender may be violated if it's not especially * careful about sending transactions invoking {multicall}. For example, a relay address that filters function * selectors won't filter calls nested within a {multicall} operation. * * NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {_msgSender}). * If a non-canonical context is identified, the following self `delegatecall` appends the last bytes of `msg.data` * to the subcall. This makes it safe to use with {ERC2771Context}. Contexts that don't affect the resolution of * {_msgSender} are not propagated to subcalls. * * _Available since v4.1._ */ abstract contract Multicall is Context { /** * @dev Receives and executes a batch of function calls on this contract. * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) { bytes memory context = msg.sender == _msgSender() ? new bytes(0) : msg.data[msg.data.length - _contextSuffixLength():]; results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { results[i] = Address.functionDelegateCall(address(this), bytes.concat(data[i], context)); } return results; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.0; import { Context } from "Context.sol"; import { StorageSlot } from "StorageSlot.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 SlotPausable is Context { // This is the keccak-256 hash of "pausable.slot" subtracted by 1 bytes32 private constant pausable_slot = 0xd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e5; function _paused() private view returns (bool) { return StorageSlot.getBooleanSlot(pausable_slot).value; } function _setPaused(bool flag) private { StorageSlot.getBooleanSlot(pausable_slot).value = flag; } /** * @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); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ constructor() { _setPaused(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 { if (paused()) revert EnforcedPause(); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) revert ExpectedPause(); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _setPaused(true); emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _setPaused(false); emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IEXBridge.sol"; import { Sig } from "UniversalTypes.sol"; import { SlotServiceSigner } from "SlotServiceSigner.sol"; abstract contract CrossBridgeBase is IEXBridgeBase, SlotServiceSigner { uint32 constant public rateBase = 10000; address public feeAccount; address public syncAccount; BridgeContractInfo pairBridgeInfo; StakingInfo stakingInfo; FeeConfig feeConfig; BridgeAmountConfig bridgeAmountConfig; IEcoERC20 remoteToken; AssetInfo localAsset; uint64 public override localNonce; mapping(uint256 sourceNonce => bool filtered) public override filterSrcNonce; mapping(uint256 withdrawalId => address account) public override filterWithdrawalId; function _useLocalNonce() internal returns (uint64) { return localNonce++; } function setFeeAccount(address _feeAccount) public override onlyOwner { feeAccount = _feeAccount; } function setSyncAccount(address _syncAccount) public override onlyOwner { syncAccount = _syncAccount; } function setBridgePairInfo(BridgeContractInfo memory _pairBridgeInfo) public override onlyOwner { require(_pairBridgeInfo.bridge != address(0), "bridge address"); require(_pairBridgeInfo.chainId != 0, "bridge chain id"); require(_pairBridgeInfo.nonce == 0, "bridge nonce"); pairBridgeInfo = _pairBridgeInfo; } function setStakingInfo(StakingInfo memory _stakingInfo) public override onlyOwner { require(_stakingInfo.stake_contract != address(0), "stake contract"); require(_stakingInfo.ncpIds.length == 1, "ncpIds"); stakingInfo = _stakingInfo; } function setFeeConfig(FeeConfig memory _feeConfig) public override onlyOwner { require(_feeConfig.rate <= rateBase, "fee rate"); require(_feeConfig.min <= _feeConfig.max, "fee range"); feeConfig = _feeConfig; } function setBridgeAmountConfig(BridgeAmountConfig memory _bridgeAmountConfig) public override onlyOwner { require(_bridgeAmountConfig.min > 0, "bridge min"); require(_bridgeAmountConfig.min < _bridgeAmountConfig.max, "bridge range"); bridgeAmountConfig = _bridgeAmountConfig; } function getSrcBridgeContractInfo() external override view returns (BridgeContractInfo memory) { return pairBridgeInfo; } function getStakingInfo() external override view returns (StakingInfo memory) { return stakingInfo; } function getFeeConfig() external override view returns (FeeConfig memory) { return feeConfig; } function getBridgeAmountConfig() external override view returns (BridgeAmountConfig memory) { return bridgeAmountConfig; } function getLocalAsset() external override view returns (AssetInfo memory) { return localAsset; } function calcBridgeTransferAmount(uint256 amount) external view override returns (uint256 transferAmount, uint256 feeAmount) { return _calcBridgeTransferAmount(amount, feeConfig, bridgeAmountConfig); } function calcFee(uint256 amount) external view returns (uint256 feeAmount) { return _calcFee(amount, feeConfig); } function recoversToRemoteMessage( uint64 nonce, ToRemoteMessageInfo memory msgToRemote, Sig[] memory sigs ) public view override returns (address[] memory signers) { BridgeContractInfo memory srcBridge = pairBridgeInfo; srcBridge.nonce = nonce; bytes32 msg_hash = keccak256(abi.encode(srcBridge, BrigeMessegeType.ToRemote, msgToRemote)); signers = new address[](sigs.length); for(uint256 i; i<sigs.length;) { signers[i] = ecrecover(msg_hash, sigs[i].v, sigs[i].r, sigs[i].s); unchecked { ++i; } } } function _verifyToRemoteMessage( uint64 nonce, ToRemoteMessageInfo memory msgToRemote, Sig[] memory sigs ) internal view { checkQuorum( recoversToRemoteMessage(nonce, msgToRemote, sigs) ); } function recoversToOriginMessage( uint64 nonce, ToOriginMessageInfo memory msgToOrigin, Sig[] memory sigs ) public view override returns (address[] memory signers) { BridgeContractInfo memory srcBridge = pairBridgeInfo; srcBridge.nonce = nonce; bytes32 msg_hash = keccak256(abi.encode(srcBridge, BrigeMessegeType.ToOrigin, msgToOrigin)); signers = new address[](sigs.length); for(uint256 i; i<sigs.length;) { signers[i] = ecrecover(msg_hash, sigs[i].v, sigs[i].r, sigs[i].s); unchecked { ++i; } } } function _verifyToOriginMessage( uint64 nonce, ToOriginMessageInfo memory msgToOrigin, Sig[] memory sigs ) internal view { checkQuorum( recoversToOriginMessage(nonce, msgToOrigin, sigs) ); } function recoversSyncMessage( uint64 nonce, uint256 amount, Sig[] memory sigs ) public view override returns (address[] memory signers) { BridgeContractInfo memory srcBridge = pairBridgeInfo; srcBridge.nonce = nonce; bytes32 msg_hash = keccak256(abi.encode(srcBridge, BrigeMessegeType.Sync, amount)); signers = new address[](sigs.length); for(uint256 i; i<sigs.length;) { signers[i] = ecrecover(msg_hash, sigs[i].v, sigs[i].r, sigs[i].s); unchecked { ++i; } } } function _verifySyncMessage( uint64 nonce, uint256 amount, Sig[] memory sigs ) internal view { checkQuorum( recoversSyncMessage(nonce, amount, sigs) ); } function _getBridgeSnapshot() internal view returns (ConfigSnapshot memory snapshot) { snapshot.bridgeAmountConfig = bridgeAmountConfig; snapshot.feeConfig = feeConfig; snapshot.localAsset = localAsset; } function _updateAssetInfo(ConfigSnapshot memory snapshot) internal { _updateAssetInfo(snapshot.localAsset); } function _updateAssetInfo(AssetInfo memory _assetInfo) internal { localAsset = _assetInfo; } function _trySendValueCatchFail( address payable recipient, uint256 amount ) internal returns (bool success) { require(address(this).balance >= amount, "fail send value"); (success, ) = recipient.call{ value: amount }(hex""); if (!success) { emit FailSendValue(recipient, amount); (bool _success, ) = payable(owner()).call{ value: amount }(hex""); require(_success, "fail amount catch"); } } function _calcBridgeTransferAmount( uint256 amount, FeeConfig memory _feeConfig, BridgeAmountConfig memory _bridgeAmountConfig ) internal pure returns (uint256 transferAmount, uint256 feeAmount) { _checkBridgeTransferAmount(amount, _bridgeAmountConfig); feeAmount = _calcFee(amount, _feeConfig); require(amount > feeAmount, "fee amount"); transferAmount = amount - feeAmount; } function _calcFee(uint256 amount, FeeConfig memory _feeConfig) internal pure returns (uint256 feeAmount) { unchecked{ feeAmount = amount * _feeConfig.rate / rateBase; } if(feeAmount < _feeConfig.min) feeAmount = _feeConfig.min; if(feeAmount > _feeConfig.max) feeAmount = _feeConfig.max; } function _checkBridgeTransferAmount(uint256 amount, BridgeAmountConfig memory _bridgeAmountConfig) internal pure { require(_bridgeAmountConfig.min <= amount, "minimum"); require(_bridgeAmountConfig.max >= amount, "maximum"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAdminable, SlotAdminable } from "SlotAdminable.sol"; import { StorageSlot } from "StorageSlot.sol"; interface ISlotServiceSigner is IAdminable { error SignerAuth(); event SignerAuthTransfer(address indexed previousSigner, address indexed newSigner); function signers(uint256 index) external returns (address); function getSigners() external returns (address[] memory); function isSigner(address signer) external returns (bool); function grantSigner(address signer) external; function revokeSigner(address signer) external; } struct AddressArraySlot { address[] signers; } struct AddressSlot { address signer; } library ServiceSignerSlot { /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function slotAddressArray(bytes32 slot) internal pure returns (address[] storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } function slotMappingToBoolean(bytes32 slot) internal pure returns (mapping(address => bool) storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } } library AddressArray { function remove(address[] storage arr, address data) internal { uint256 len = arr.length; for(uint256 i; i<len;) { if(data == arr[i]) { arr[i] = arr[len-1]; arr.pop(); return; } unchecked{ ++i; } } } } contract SlotServiceSigner is ISlotServiceSigner, SlotAdminable { // This is the keccak-256 hash of "service.signer.address.mapping.slot" subtracted by 1 // will use for array and mapping bytes32 private constant _SIGNER_SLOT = 0xf237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b; using ServiceSignerSlot for bytes32; using AddressArray for address[]; function signers(uint256 index) public view returns (address) { return _SIGNER_SLOT.slotAddressArray()[index]; } function signersLength() public view returns (uint256) { return _SIGNER_SLOT.slotAddressArray().length; } function getSigners() public view returns (address[] memory) { // todo: mutability bug? return _SIGNER_SLOT.slotAddressArray(); } function isSigner(address signer) public override view returns (bool) { return _SIGNER_SLOT.slotMappingToBoolean()[signer]; } function grantSigner(address signer) public override onlyAuthorized { _transferSignerAuth(address(0), signer); } function revokeSigner(address signer) public override onlyAuthorized { _transferSignerAuth(signer, address(0)); } function checkQuorum(address[] memory _signers) public view { uint256 len = _signers.length; // len >= total // 2 + 1 require(len >= (_SIGNER_SLOT.slotAddressArray().length >> 1) + 1, "quorum"); if(len > 1) { uint256 limit = len-1; for(uint256 i; i < limit;) { // avoid signature reuse require(_signers[i] < _signers[i+1], "Ascending Order"); unchecked{ ++i; } } } mapping(address => bool) storage signerMap = _SIGNER_SLOT.slotMappingToBoolean(); for(uint256 i; i < len;) { require(signerMap[ _signers[i] ], "invalid signer"); unchecked{ ++i; } } } function _getSignerMapSlot(address signer) internal pure returns (StorageSlot.BooleanSlot storage) { // evm mapping slot: keccak256( abi.encode(<KEY>, <MAPPING_POSITION>) ) return StorageSlot.getBooleanSlot(keccak256(abi.encode(signer, _SIGNER_SLOT))); } function _setSignerFlag(address signer, bool flag) internal { if (signer != address(0)) { if (_SIGNER_SLOT.slotMappingToBoolean()[signer] == flag) revert SignerAuth(); _SIGNER_SLOT.slotMappingToBoolean()[signer] = flag; if(flag) _SIGNER_SLOT.slotAddressArray().push( signer ); else _SIGNER_SLOT.slotAddressArray().remove( signer ); } } function _transferSignerAuth(address old_signer, address new_signer) internal { _setSignerFlag(old_signer, false); _setSignerFlag(new_signer, true); emit SignerAuthTransfer(old_signer, new_signer); } }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 1000000 }, "libraries": { "CrossBridgeOrigin.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"address","name":"stake_contract","type":"address"},{"internalType":"uint8[]","name":"ncpIds","type":"uint8[]"}],"internalType":"struct StakingInfo","name":"_stakingInfo","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Adminship","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"SignerAuth","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FailSendValue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"ncpId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"ReceiveComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"ncpId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReceivePending","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousSigner","type":"address"},{"indexed":true,"internalType":"address","name":"newSigner","type":"address"}],"name":"SignerAuthTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"localNonce","type":"uint64"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"srcNonce","type":"uint64"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ToOriginReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"localNonce","type":"uint64"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"ToRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calcBridgeTransferAmount","outputs":[{"internalType":"uint256","name":"transferAmount","type":"uint256"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calcFee","outputs":[{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"call","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_signers","type":"address[]"}],"name":"checkQuorum","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ncpId","type":"uint256"},{"internalType":"uint256","name":"withdrawalId","type":"uint256"}],"name":"completeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sourceNonce","type":"uint256"}],"name":"filterSrcNonce","outputs":[{"internalType":"bool","name":"filtered","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"withdrawalId","type":"uint256"}],"name":"filterWithdrawalId","outputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBridgeAmountConfig","outputs":[{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint128","name":"toOriginNativeFee","type":"uint128"},{"internalType":"uint128","name":"toRemoteNativeSwapAmount","type":"uint128"}],"internalType":"struct BridgeAmountConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeConfig","outputs":[{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint32","name":"rate","type":"uint32"}],"internalType":"struct FeeConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLocalAsset","outputs":[{"components":[{"internalType":"uint128","name":"bridgeTotalLocked","type":"uint128"},{"internalType":"uint128","name":"bridgeTotalSyncStaking","type":"uint128"}],"internalType":"struct AssetInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSigners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSrcBridgeContractInfo","outputs":[{"components":[{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"address","name":"bridge","type":"address"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct BridgeContractInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingInfo","outputs":[{"components":[{"internalType":"address","name":"stake_contract","type":"address"},{"internalType":"uint8[]","name":"ncpIds","type":"uint8[]"}],"internalType":"struct StakingInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"grantSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"grant_admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"address","name":"stake_contract","type":"address"},{"internalType":"uint8[]","name":"ncpIds","type":"uint8[]"}],"internalType":"struct StakingInfo","name":"_stakingInfo","type":"tuple"}],"name":"initCrossBridgeOrigin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"is_admin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateBase","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Sig[]","name":"sigs","type":"tuple[]"}],"name":"recoversSyncMessage","outputs":[{"internalType":"address[]","name":"signers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ToOriginMessageInfo","name":"msgToOrigin","type":"tuple"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Sig[]","name":"sigs","type":"tuple[]"}],"name":"recoversToOriginMessage","outputs":[{"internalType":"address[]","name":"signers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountForNativeAlloc","type":"uint256"}],"internalType":"struct ToRemoteMessageInfo","name":"msgToRemote","type":"tuple"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Sig[]","name":"sigs","type":"tuple[]"}],"name":"recoversToRemoteMessage","outputs":[{"internalType":"address[]","name":"signers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceAdminship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"srcNonce","type":"uint64"},{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ToOriginMessageInfo","name":"msgBridge","type":"tuple"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Sig[]","name":"sigs","type":"tuple[]"}],"name":"requestReceive","outputs":[{"internalType":"uint256[]","name":"withdrawalIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"revokeSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"revoke_admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint128","name":"toOriginNativeFee","type":"uint128"},{"internalType":"uint128","name":"toRemoteNativeSwapAmount","type":"uint128"}],"internalType":"struct BridgeAmountConfig","name":"_bridgeAmountConfig","type":"tuple"}],"name":"setBridgeAmountConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"address","name":"bridge","type":"address"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct BridgeContractInfo","name":"_pairBridgeInfo","type":"tuple"}],"name":"setBridgePairInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAccount","type":"address"}],"name":"setFeeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint32","name":"rate","type":"uint32"}],"internalType":"struct FeeConfig","name":"_feeConfig","type":"tuple"}],"name":"setFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"stake_contract","type":"address"},{"internalType":"uint8[]","name":"ncpIds","type":"uint8[]"}],"internalType":"struct StakingInfo","name":"_stakingInfo","type":"tuple"}],"name":"setStakingInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_syncAccount","type":"address"}],"name":"setSyncAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"signers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signersLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"syncAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"toRemote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162005c4038038062005c4083398101604081905262000034916200062c565b6200003f336200007c565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e5805460ff19169055620000748282620000c6565b50506200074c565b6000620000976000546201000090046001600160a01b031690565b9050620000a481620001fd565b15620000b757620000b781600062000214565b620000c28262000272565b5050565b600054610100900460ff1615808015620000e75750600054600160ff909116105b80620001035750303b15801562000103575060005460ff166001145b6200016c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000190576000805461ff0019166101001790555b6200019b336200007c565b620001a682620002d0565b620001b1836200007c565b8015620001f8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006200020a82620003a7565b5460ff1692915050565b6200022182600062000415565b6200022e81600162000415565b806001600160a01b0316826001600160a01b03167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b600080546001600160a01b038381166201000081810262010000600160b01b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b90565b620002da62000472565b80516001600160a01b0316620003245760405162461bcd60e51b815260206004820152600e60248201526d1cdd185ad94818dbdb9d1c9858dd60921b604482015260640162000163565b806020015151600114620003645760405162461bcd60e51b81526020600482015260066024820152656e637049647360d01b604482015260640162000163565b8051600480546001600160a01b0319166001600160a01b039092169190911781556020808301518051849392620003a192600592910190620004d7565b50505050565b604080516001600160a01b03831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b918101919091526000906200040f9060600160405160208183030381529060405280519060200120620002cd60201b60201c565b92915050565b6001600160a01b03821615620000c25760006200043283620003a7565b805490915082151560ff909116151503620004605760405163053db68960e51b815260040160405180910390fd5b805482151560ff199091161790555050565b6000546001600160a01b0362010000909104163314620004d55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000163565b565b82805482825590600052602060002090601f01602090048101928215620005725791602002820160005b838211156200054157835183826101000a81548160ff021916908360ff160217905550926020019260010160208160000104928301926001030262000501565b8015620005705782816101000a81549060ff021916905560010160208160000104928301926001030262000541565b505b506200058092915062000584565b5090565b5b8082111562000580576000815560010162000585565b80516001600160a01b0381168114620005b357600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620005f357620005f3620005b8565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006245762000624620005b8565b604052919050565b600080604083850312156200064057600080fd5b6200064b836200059b565b602084810151919350906001600160401b03808211156200066b57600080fd5b90850190604082880312156200068057600080fd5b6200068a620005ce565b62000695836200059b565b81528383015182811115620006a957600080fd5b80840193505087601f840112620006bf57600080fd5b825182811115620006d457620006d4620005b8565b8060051b9250620006e7858401620005f9565b818152928401850192858101908a8511156200070257600080fd5b948601945b8486101562000736578551925060ff83168314620007255760008081fd5b828252948601949086019062000707565b8087850152505050809450505050509250929050565b6154e4806200075c6000396000f3fe60806040526004361061030c5760003560e01c806375dc7d8c1161019a578063b71c1179116100e1578063d2a45ab51161008a578063ecd9d60f11610064578063ecd9d60f14610b4e578063f2fde38b14610b6e578063fff6cae914610b8e57600080fd5b8063d2a45ab514610aee578063defb794e14610b0e578063e7bd373914610b2e57600080fd5b8063c298ffa8116100bb578063c298ffa814610a81578063c34b44a014610aa1578063ce0a7e7a14610ac157600080fd5b8063b71c117914610a39578063b88a802f14610a4c578063be83f92d14610a6157600080fd5b80639bed25d811610143578063ac9650d81161011d578063ac9650d8146109ca578063b05e6a35146109f7578063b40cd21d14610a1757600080fd5b80639bed25d814610952578063a8edb3d114610967578063aac132de146109aa57600080fd5b80638456cb59116101745780638456cb59146108ea5780638da5cb5b146108ff57806394cf795e1461093057600080fd5b806375dc7d8c146107935780637df73e27146107b3578063812db1be1461081857600080fd5b80635c975abb1161025e57806363c724f7116102075780636f760d6c116101e15780636f760d6c1461071c578063715018a614610749578063715bfe511461075e57600080fd5b806363c724f7146106ae57806365e17c9d146106ce5780636dbf2fa0146106fb57600080fd5b8063615f32ed11610238578063615f32ed1461063e578063628484ab1461065e578063629866b21461068e57600080fd5b80635c975abb146105bc5780635d334185146105e15780635fbbc0d21461060157600080fd5b80632ca3998d116102c05780634535b1131161029a5780634535b113146104d85780634b023cf8146104f85780635982fd201461051857600080fd5b80632ca3998d1461040f5780633f4ba83a1461048557806341f684f31461049a57600080fd5b806313cb3591116102f157806313cb3591146103705780632079fb9a146103aa5780632465e58e146103ef57600080fd5b8063014e95ba1461032057806308f496dd1461035057600080fd5b3661031b57610319610b96565b005b600080fd5b34801561032c57600080fd5b5061033661271081565b60405163ffffffff90911681526020015b60405180910390f35b34801561035c57600080fd5b5061031961036b366004614657565b610bd7565b34801561037c57600080fd5b50600e546103919067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610347565b3480156103b657600080fd5b506103ca6103c5366004614674565b610bed565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610347565b3480156103fb57600080fd5b5061031961040a366004614657565b610c49565b34801561041b57600080fd5b50604080518082018252600080825260209182015281518083018352600d546fffffffffffffffffffffffffffffffff8082168084527001000000000000000000000000000000009092048116928401928352845191825291519091169181019190915201610347565b34801561049157600080fd5b50610319610c98565b3480156104a657600080fd5b507ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b545b604051908152602001610347565b3480156104e457600080fd5b506103196104f3366004614770565b610d33565b34801561050457600080fd5b50610319610513366004614657565b610e72565b34801561052457600080fd5b506105af6040805160608101825260008082526020820181905291810191909152506040805160608101825260035463ffffffff81168252640100000000810473ffffffffffffffffffffffffffffffffffffffff1660208301527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169181019190915290565b60405161034791906147b0565b3480156105c857600080fd5b506105d1610ec1565b6040519015158152602001610347565b3480156105ed57600080fd5b506103196105fc3660046148e8565b610ef3565b34801561060d57600080fd5b5061061661109a565b6040805182518152602080840151908201529181015163ffffffff1690820152606001610347565b34801561064a57600080fd5b50610319610659366004614938565b6110ef565b34801561066a57600080fd5b506105d1610679366004614674565b600f6020526000908152604090205460ff1681565b34801561069a57600080fd5b506103196106a936600461498d565b61124a565b3480156106ba57600080fd5b506103196106c9366004614657565b61136f565b3480156106da57600080fd5b506001546103ca9073ffffffffffffffffffffffffffffffffffffffff1681565b61070e6107093660046149fe565b61140d565b604051610347929190614af5565b34801561072857600080fd5b5061073c610737366004614bc3565b611491565b6040516103479190614c69565b34801561075557600080fd5b5061031961166f565b34801561076a57600080fd5b5061077e610779366004614674565b611681565b60408051928352602083019190915201610347565b34801561079f57600080fd5b506104ca6107ae366004614674565b611714565b3480156107bf57600080fd5b506105d16107ce366004614657565b73ffffffffffffffffffffffffffffffffffffffff1660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205460ff1690565b34801561082457600080fd5b506108a160408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526009548152600a546020820152600b546fffffffffffffffffffffffffffffffff808216938301939093527001000000000000000000000000000000009004909116606082015290565b604080518251815260208084015190820152828201516fffffffffffffffffffffffffffffffff9081169282019290925260609283015190911691810191909152608001610347565b3480156108f657600080fd5b5061031961174f565b34801561090b57600080fd5b5060005462010000900473ffffffffffffffffffffffffffffffffffffffff166103ca565b34801561093c57600080fd5b506109456117ea565b6040516103479190614ca1565b34801561095e57600080fd5b50610319611878565b34801561097357600080fd5b506103ca610982366004614674565b60106020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156109b657600080fd5b506105d16109c5366004614657565b611883565b3480156109d657600080fd5b506109ea6109e5366004614cef565b611898565b6040516103479190614d64565b348015610a0357600080fd5b50610319610a12366004614de6565b611980565b348015610a2357600080fd5b50610a2c611b98565b6040516103479190614e2a565b610319610a47366004614657565b611c4e565b348015610a5857600080fd5b50610319611d85565b348015610a6d57600080fd5b50610319610a7c366004614657565b611e11565b348015610a8d57600080fd5b50610319610a9c366004614e9b565b611e24565b348015610aad57600080fd5b50610319610abc366004614657565b6120a1565b348015610acd57600080fd5b506002546103ca9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610afa57600080fd5b50610945610b09366004614bc3565b61213f565b348015610b1a57600080fd5b50610319610b29366004614f35565b612316565b348015610b3a57600080fd5b50610945610b49366004614f57565b61232c565b348015610b5a57600080fd5b50610945610b69366004614f98565b6124f9565b348015610b7a57600080fd5b50610319610b89366004614657565b6126c6565b61031961277a565b610b9e610ec1565b15610bd5576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b610bdf612920565b610bea6000826129a8565b50565b60007ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b8281548110610c2157610c21615032565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1692915050565b610c51612920565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610ca133611883565b80610cf5575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610d2b576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd5612a1c565b610d3b612920565b61271063ffffffff16816040015163ffffffff161115610dbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f666565207261746500000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b602081015181511115610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6665652072616e676500000000000000000000000000000000000000000000006044820152606401610db3565b8051600655602081015160075560400151600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091179055565b610e7a612920565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610eee7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e55460ff1690565b905090565b600054610100900460ff1615808015610f135750600054600160ff909116105b80610f2d5750303b158015610f2d575060005460ff166001145b610fb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610db3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561101757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61102033612ab8565b611029826110ef565b61103283612ab8565b801561109557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6110c460405180606001604052806000815260200160008152602001600063ffffffff1681525090565b50604080516060810182526006548152600754602082015260085463ffffffff169181019190915290565b6110f7612920565b805173ffffffffffffffffffffffffffffffffffffffff16611175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b6520636f6e74726163740000000000000000000000000000000000006044820152606401610db3565b8060200151516001146111e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e637049647300000000000000000000000000000000000000000000000000006044820152606401610db3565b8051600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117815560208083015180518493926112449260059291019061457a565b50505050565b611252612920565b80516112ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f627269646765206d696e000000000000000000000000000000000000000000006044820152606401610db3565b6020810151815110611328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6272696467652072616e676500000000000000000000000000000000000000006044820152606401610db3565b80516009556020810151600a5560408101516060909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600b55565b61137833611883565b806113cc575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611402576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bea600082612af9565b60006060611419612920565b8573ffffffffffffffffffffffffffffffffffffffff16858585604051611441929190615061565b60006040518083038185875af1925050503d806000811461147e576040519150601f19603f3d011682016040523d82523d6000602084013e611483565b606091505b509150915094509492505050565b606061149b610b96565b67ffffffffffffffff84166000908152600f602052604090205460ff161561151f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f737263206e6f6e636500000000000000000000000000000000000000000000006044820152606401610db3565b67ffffffffffffffff84166000908152600f6020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611569612b6d565b905061157781868686612c73565b604082015261158584612d2b565b91506115c6816040015180516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152611666958086019391929083018282801561165857602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116116295790505b50505050508152505061316d565b50509392505050565b611677612920565b610bd56000612ab8565b6040805160608082018352600654825260075460208084019190915260085463ffffffff168385015283516080810185526009548152600a5491810191909152600b546fffffffffffffffffffffffffffffffff80821695830195909552700100000000000000000000000000000000900490931690830152600091829161170b918591906132f8565b91509150915091565b604080516060810182526006548152600754602082015260085463ffffffff169181019190915260009061174990839061338e565b92915050565b61175833611883565b806117ac575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6117e2576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd56133c8565b60607ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b80548060200260200160405190810160405280929190818152602001828054801561186e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611843575b5050505050905090565b610bd53360006129a8565b600061188e82613441565b5460ff1692915050565b6040805160008152602081019091526060908267ffffffffffffffff8111156118c3576118c361468d565b6040519080825280602002602001820160405280156118f657816020015b60608152602001906001900390816118e15790505b50915060005b83811015611978576119533086868481811061191a5761191a615032565b905060200281019061192c91906150b3565b8560405160200161193f93929190615118565b6040516020818303038152906040526134ac565b83828151811061196557611965615032565b60209081029190910101526001016118fc565b505092915050565b611988612920565b602081015173ffffffffffffffffffffffffffffffffffffffff16611a09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f62726964676520616464726573730000000000000000000000000000000000006044820152606401610db3565b805163ffffffff16600003611a7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f62726964676520636861696e20696400000000000000000000000000000000006044820152606401610db3565b604081015167ffffffffffffffff1615611af0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f627269646765206e6f6e636500000000000000000000000000000000000000006044820152606401610db3565b805160038054602084015160409094015167ffffffffffffffff1678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff909516640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921663ffffffff909416939093171792909216179055565b6040805180820190915260008152606060208201526040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152939492938386019390929190830182828015611c4057602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411611c115790505b505050505081525050905090565b611c56610b96565b73ffffffffffffffffffffffffffffffffffffffff8116611c745750335b611c7d346134d8565b6000611c87612b6d565b9050611cbf8160405180604001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020013481525060016136bf565b60408201819052611d019080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526110959580860193919290830182828015611658576000918252602091829020805460ff16845290820283019290916001910180841161162957905050505050508152505061316d565b611d8d610b96565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152610bea9580860193919290830182828015611658576000918252602091829020805460ff16845290820283019290916001910180841161162957905050505050508152505061316d565b611e19612920565b610bea8160006129a8565b805160017ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b54611e56911c600161513f565b811015611ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f71756f72756d00000000000000000000000000000000000000000000000000006044820152606401610db3565b6001811115611fbe576000611ed56001836150a0565b905060005b81811015611fbb5783611eee82600161513f565b81518110611efe57611efe615032565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16848281518110611f2e57611f2e615032565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611fb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f417363656e64696e67204f7264657200000000000000000000000000000000006044820152606401610db3565b600101611eda565b50505b7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b60005b8281101561124457816000858381518110611fff57611fff615032565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff16612099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c6964207369676e65720000000000000000000000000000000000006044820152606401610db3565b600101611fe2565b6120aa33611883565b806120fe575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612134576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bea816000612af9565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff871683850152925190926000916121a491849160029189910161518d565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156121d6576121d661468d565b6040519080825280602002602001820160405280156121ff578160200160208202803683370190505b50925060005b845181101561230c5760018286838151811061222357612223615032565b60200260200101516000015187848151811061224157612241615032565b60200260200101516020015188858151811061225f5761225f615032565b602002602001015160400151604051600081526020016040526040516122a1949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156122c3573d6000803e3d6000fd5b505050602060405103518482815181106122df576122df615032565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612205565b5050509392505050565b61231e610b96565b612328828261382d565b5050565b60408051606080820183526003805463ffffffff81168452640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208085019190915267ffffffffffffffff88168486015293519193600092612391928592909189910161520b565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156123c3576123c361468d565b6040519080825280602002602001820160405280156123ec578160200160208202803683370190505b50925060005b845181101561230c5760018286838151811061241057612410615032565b60200260200101516000015187848151811061242e5761242e615032565b60200260200101516020015188858151811061244c5761244c615032565b6020026020010151604001516040516000815260200160405260405161248e949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156124b0573d6000803e3d6000fd5b505050602060405103518482815181106124cc576124cc615032565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016123f2565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff8716838501529251909260009161255e918491600191899101615268565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156125905761259061468d565b6040519080825280602002602001820160405280156125b9578160200160208202803683370190505b50925060005b845181101561230c576001828683815181106125dd576125dd615032565b6020026020010151600001518784815181106125fb576125fb615032565b60200260200101516020015188858151811061261957612619615032565b6020026020010151604001516040516000815260200160405260405161265b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561267d573d6000803e3d6000fd5b5050506020604051035184828151811061269957612699615032565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016125bf565b6126ce612920565b73ffffffffffffffffffffffffffffffffffffffff8116612771576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610db3565b610bea81612ab8565b612782610b96565b600061278c612b6d565b60025490915073ffffffffffffffffffffffffffffffffffffffff16338114612813576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db39060208082526004908201527f73796e6300000000000000000000000000000000000000000000000000000000604082015260600190565b61281c346134d8565b34826040015160000181815161283291906152f0565b6fffffffffffffffffffffffffffffffff169052506040820151602001805134919061285f9083906152f0565b6fffffffffffffffffffffffffffffffff1690525060408201516128b49080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006128be613b5f565b90508173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f6a28c316db1c85974981164e2be540ab36fb82b391d0dfda369f948d1474de173460405161291391815260200190565b60405180910390a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff62010000909104163314610bd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db3565b6129b3826000613ba8565b6129be816001613ba8565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b612a24613c45565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16612ae081611883565b15612af057612af08160006129a8565b61232882613c83565b612b04826000613d01565b612b0f816001613d01565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f9d188613a1a9a2ea26521bec252487f1739a344d8ffe6ef61cd7bca567d8f3d160405160405180910390a35050565b612bd16040805160c08101825260006060808301828152608080850184905260a08501849052908452845190810185528281526020808201849052818601849052918101839052818401528351808501855282815290810191909152909182015290565b604080516080810182526009548152600a54602080830191909152600b546fffffffffffffffffffffffffffffffff80821684860152700100000000000000000000000000000000918290048116606080860191909152868401949094528451938401855260065484526007548484015260085463ffffffff168486015292855283518085018552600d54808516825291909104909216908201529082015290565b6040805180820190915260008082526020820152612c92848484613ebc565b602083015160408601518051612ca9908390615319565b6fffffffffffffffffffffffffffffffff16905250825160208085015160405190815273ffffffffffffffffffffffffffffffffffffffff9092169167ffffffffffffffff8716917fca798eef187f833f790884379ed453edfc01901535dc3083866f8446dc25f0f8910160405180910390a35060408401515b949350505050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526060956000959493818601939091830182828015612dc057602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612d915790505b5050505050815250509050600081600001519050600080612de5848760200151613eca565b915091506000805b835181101561316157828181518110612e0857612e08615032565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e09818858381518110612e5257612e52615032565b6020026020010151868481518110612e6c57612e6c615032565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af1158015612ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f159190615342565b838281518110612f2757612f27615032565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff1660106000858481518110612f8757612f87615032565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614613031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401610db3565b87600001516010600085848151811061304c5761304c615032565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508381815181106130c4576130c4615032565b602002602001015160ff16886000015173ffffffffffffffffffffffffffffffffffffffff167f4833244c0517cc1688428ff8842d0c253c9cea94b95f61d91a680203b55ebf0185848151811061311d5761311d615032565b6020026020010151856040516131519291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a3600101612ded565b50909695505050505050565b60025460009073ffffffffffffffffffffffffffffffffffffffff16806131f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f73796e63207a65726f00000000000000000000000000000000000000000000006044820152606401610db3565b825173ffffffffffffffffffffffffffffffffffffffff821631925060005b8460200151518110156132d6578173ffffffffffffffffffffffffffffffffffffffff1663ddd5e1b28660200151838151811061324e5761324e615032565b6020026020010151856040518363ffffffff1660e01b815260040161329892919060ff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156132b257600080fd5b505af11580156132c6573d6000803e3d6000fd5b50506001909201915061320f9050565b50612d238373ffffffffffffffffffffffffffffffffffffffff8416316150a0565b6000806133058584613ee3565b61330f858561338e565b905080851161337a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401610db3565b61338481866150a0565b9150935093915050565b6040810151815161271063ffffffff909216840291909104908110156133b2575080515b8160200151811115611749575060200151919050565b6133d0610b96565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833612a8e565b6040805173ffffffffffffffffffffffffffffffffffffffff831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b91810191909152600090611749906060016040516020818303038152906040528051906020012090565b60606134d1838360405180606001604052806027815260200161548860279139613fbc565b9392505050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526000958086019391929083018282801561356957602002820191906000526020600020906000905b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161353a5790505b505050919092525050815191925060009050806135868486614041565b9150915060005b82518110156136b7578373ffffffffffffffffffffffffffffffffffffffff16636366ebe38383815181106135c4576135c4615032565b60200260200101516fffffffffffffffffffffffffffffffff168584815181106135f0576135f0615032565b602002602001015185858151811061360a5761360a615032565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260ff90921660048301526fffffffffffffffffffffffffffffffff166024820152306044820152600060648201819052608482015260a4016000604051808303818588803b15801561369257600080fd5b505af11580156136a6573d6000803e3d6000fd5b50506001909301925061358d915050565b505050505050565b604080518082019091526000808252602082015260006136e784602001518660200151613ee3565b821561377a576136ff8460200151866000015161338e565b90508084602001511161376e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401610db3565b60208401805182900390525b6020840151604086015180516137919083906152f0565b6fffffffffffffffffffffffffffffffff1690525060006137b0613b5f565b9050846000015173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f87c8e141595387353b9f5800de2510b7678d07b38c7e01c29ab619d7938e6396876020015185604051613816929190918252602082015260400190565b60405180910390a350505060408301519392505050565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff16806138b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401610db3565b600082815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556004805482517f83453945000000000000000000000000000000000000000000000000000000008152925173ffffffffffffffffffffffffffffffffffffffff909116949385936383453945938181019391829003018187875af115801561395c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613980919061535b565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b81526004016139ba91815260200190565b60e060405180830381865afa1580156139d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139fb9190615378565b606001516040517f0ad58d2f000000000000000000000000000000000000000000000000000000008152600481018790526024810186905273ffffffffffffffffffffffffffffffffffffffff85811660448301529192504791841690630ad58d2f90606401600060405180830381600087803b158015613a7b57600080fd5b505af1158015613a8f573d6000803e3d6000fd5b50505050818147613aa091906150a0565b14613b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401610db3565b613b118483614129565b5084868573ffffffffffffffffffffffffffffffffffffffff167f56938cd8bd3b7e9e03d3414d2307365bc79aa14190fc2b22e7119ad2ba26c48160405160405180910390a4505050505050565b600e805460009167ffffffffffffffff9091169082613b7d83615402565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905090565b73ffffffffffffffffffffffffffffffffffffffff821615612328576000613bcf83613441565b805490915082151560ff909116151503613c15576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80548215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790555050565b613c4d610ec1565b610bd5576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b73ffffffffffffffffffffffffffffffffffffffff8216156123285773ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205481151560ff909116151503613da3576040517fd4be6f0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215801591909117909155613e92577ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b80546001810182556000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555050565b6123287ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b83614339565b611095610a9c84848461213f565b606080613ed78484614041565b915091505b9250929050565b8051821015613f4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d696e696d756d000000000000000000000000000000000000000000000000006044820152606401610db3565b8181602001511015612328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d6178696d756d000000000000000000000000000000000000000000000000006044820152606401610db3565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051613fe69190615429565b600060405180830381855af49150503d8060008114614021576040519150601f19603f3d011682016040523d82523d6000602084013e614026565b606091505b50915091506140378683838761449b565b9695505050505050565b6060808360200151516001146140b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f64656661756c74206e63704964000000000000000000000000000000000000006044820152606401610db3565b602084015160408051600180825281830190925291935081602001602082028036833701905050905082816000815181106140f0576140f0615032565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff16815250509250929050565b600081471015614195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6661696c2073656e642076616c756500000000000000000000000000000000006044820152606401610db3565b60405173ffffffffffffffffffffffffffffffffffffffff8416908390600081818185875af1925050503d80600081146141eb576040519150601f19603f3d011682016040523d82523d6000602084013e6141f0565b606091505b50508091505080611749578273ffffffffffffffffffffffffffffffffffffffff167f7a8da3fbf14e43fbfd79d8ce7ab913a13000dbbd248e9442988476e9e4b94cd88360405161424391815260200190565b60405180910390a26000805462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d80600081146142c2576040519150601f19603f3d011682016040523d82523d6000602084013e6142c7565b606091505b5050905080614332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6661696c20616d6f756e742063617463680000000000000000000000000000006044820152606401610db3565b5092915050565b815460005b818110156112445783818154811061435857614358615032565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff9081169084160361449357836143906001846150a0565b815481106143a0576143a0615032565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168482815481106143dd576143dd615032565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508380548061443557614435615445565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b60010161433e565b6060831561453157825160000361452a5773ffffffffffffffffffffffffffffffffffffffff85163b61452a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610db3565b5081612d23565b612d2383838151156145465781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db39190615474565b82805482825590600052602060002090601f016020900481019282156146105791602002820160005b838211156145e157835183826101000a81548160ff021916908360ff16021790555092602001926001016020816000010492830192600103026145a3565b801561460e5782816101000a81549060ff02191690556001016020816000010492830192600103026145e1565b505b5061461c929150614620565b5090565b5b8082111561461c5760008155600101614621565b73ffffffffffffffffffffffffffffffffffffffff81168114610bea57600080fd5b60006020828403121561466957600080fd5b81356134d181614635565b60006020828403121561468657600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156146df576146df61468d565b60405290565b6040805190810167ffffffffffffffff811182821017156146df576146df61468d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561474f5761474f61468d565b604052919050565b803563ffffffff8116811461476b57600080fd5b919050565b60006060828403121561478257600080fd5b61478a6146bc565b82358152602083013560208201526147a460408401614757565b60408201529392505050565b815163ffffffff16815260208083015173ffffffffffffffffffffffffffffffffffffffff169082015260408083015167ffffffffffffffff169082015260608101611749565b600067ffffffffffffffff8211156148115761481161468d565b5060051b60200190565b803560ff8116811461476b57600080fd5b60006040828403121561483e57600080fd5b6148466146e5565b9050813561485381614635565b815260208281013567ffffffffffffffff81111561487057600080fd5b8301601f8101851361488157600080fd5b803561489461488f826147f7565b614708565b81815260059190911b820183019083810190878311156148b357600080fd5b928401925b828410156148d8576148c98461481b565b825292840192908401906148b8565b8085870152505050505092915050565b600080604083850312156148fb57600080fd5b823561490681614635565b9150602083013567ffffffffffffffff81111561492257600080fd5b61492e8582860161482c565b9150509250929050565b60006020828403121561494a57600080fd5b813567ffffffffffffffff81111561496157600080fd5b612d238482850161482c565b80356fffffffffffffffffffffffffffffffff8116811461476b57600080fd5b60006080828403121561499f57600080fd5b6040516080810181811067ffffffffffffffff821117156149c2576149c261468d565b806040525082358152602083013560208201526149e16040840161496d565b60408201526149f26060840161496d565b60608201529392505050565b60008060008060608587031215614a1457600080fd5b8435614a1f81614635565b935060208501359250604085013567ffffffffffffffff80821115614a4357600080fd5b818701915087601f830112614a5757600080fd5b813581811115614a6657600080fd5b886020828501011115614a7857600080fd5b95989497505060200194505050565b60005b83811015614aa2578181015183820152602001614a8a565b50506000910152565b60008151808452614ac3816020860160208601614a87565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8215158152604060208201526000612d236040830184614aab565b803567ffffffffffffffff8116811461476b57600080fd5b600082601f830112614b3957600080fd5b81356020614b4961488f836147f7565b82815260609283028501820192828201919087851115614b6857600080fd5b8387015b85811015614bb65781818a031215614b845760008081fd5b614b8c6146bc565b614b958261481b565b81528186013586820152604080830135908201528452928401928101614b6c565b5090979650505050505050565b60008060008385036080811215614bd957600080fd5b614be285614b10565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082011215614c1457600080fd5b50614c1d6146e5565b6020850135614c2b81614635565b8152604085013560208201529150606084013567ffffffffffffffff811115614c5357600080fd5b614c5f86828701614b28565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561316157835183529284019291840191600101614c85565b6020808252825182820181905260009190848201906040850190845b8181101561316157835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614cbd565b60008060208385031215614d0257600080fd5b823567ffffffffffffffff80821115614d1a57600080fd5b818501915085601f830112614d2e57600080fd5b813581811115614d3d57600080fd5b8660208260051b8501011115614d5257600080fd5b60209290920196919550909350505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614dd9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452614dc7858351614aab565b94509285019290850190600101614d8d565b5092979650505050505050565b600060608284031215614df857600080fd5b614e006146bc565b614e0983614757565b81526020830135614e1981614635565b60208201526147a460408401614b10565b6020808252825173ffffffffffffffffffffffffffffffffffffffff16828201528281015160408084015280516060840181905260009291820190839060808601905b80831015614e9057835160ff168252928401926001929092019190840190614e6d565b509695505050505050565b60006020808385031215614eae57600080fd5b823567ffffffffffffffff811115614ec557600080fd5b8301601f81018513614ed657600080fd5b8035614ee461488f826147f7565b81815260059190911b82018301908381019087831115614f0357600080fd5b928401925b82841015614f2a578335614f1b81614635565b82529284019290840190614f08565b979650505050505050565b60008060408385031215614f4857600080fd5b50508035926020909101359150565b600080600060608486031215614f6c57600080fd5b614f7584614b10565b925060208401359150604084013567ffffffffffffffff811115614c5357600080fd5b600080600083850360a0811215614fae57600080fd5b614fb785614b10565b935060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082011215614fe957600080fd5b50614ff26146bc565b602085013561500081614635565b815260408581013560208301526060860135908201529150608084013567ffffffffffffffff811115614c5357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561174957611749615071565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126150e857600080fd5b83018035915067ffffffffffffffff82111561510357600080fd5b602001915036819003821315613edc57600080fd5b828482376000838201600081528351615135818360208801614a87565b0195945050505050565b8082018082111561174957611749615071565b60048110615189577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260c081016151dc6060830185615152565b73ffffffffffffffffffffffffffffffffffffffff8351166080830152602083015160a0830152949350505050565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260a0810161525a6060830185615152565b826080830152949350505050565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260e081016152b76060830185615152565b73ffffffffffffffffffffffffffffffffffffffff8351166080830152602083015160a0830152604083015160c0830152949350505050565b6fffffffffffffffffffffffffffffffff81811683821601908082111561433257614332615071565b6fffffffffffffffffffffffffffffffff82811682821603908082111561433257614332615071565b60006020828403121561535457600080fd5b5051919050565b60006020828403121561536d57600080fd5b81516134d181614635565b600060e0828403121561538a57600080fd5b60405160e0810181811067ffffffffffffffff821117156153ad576153ad61468d565b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301516153f681614635565b60c08201529392505050565b600067ffffffffffffffff80831681810361541f5761541f615071565b6001019392505050565b6000825161543b818460208701614a87565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6020815260006134d16020830184614aab56fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fdb6ba83f728e5392faff07831cb2795776710580c3d03aa2c41f045bbc8d35864736f6c634300081700330000000000000000000000007d76ae60dcc2fdb57d3924024e2ad940b76ef81f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000006af09e1a3c886dd8560bf4cabd65db16ea2724d8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000029
Deployed Bytecode
0x60806040526004361061030c5760003560e01c806375dc7d8c1161019a578063b71c1179116100e1578063d2a45ab51161008a578063ecd9d60f11610064578063ecd9d60f14610b4e578063f2fde38b14610b6e578063fff6cae914610b8e57600080fd5b8063d2a45ab514610aee578063defb794e14610b0e578063e7bd373914610b2e57600080fd5b8063c298ffa8116100bb578063c298ffa814610a81578063c34b44a014610aa1578063ce0a7e7a14610ac157600080fd5b8063b71c117914610a39578063b88a802f14610a4c578063be83f92d14610a6157600080fd5b80639bed25d811610143578063ac9650d81161011d578063ac9650d8146109ca578063b05e6a35146109f7578063b40cd21d14610a1757600080fd5b80639bed25d814610952578063a8edb3d114610967578063aac132de146109aa57600080fd5b80638456cb59116101745780638456cb59146108ea5780638da5cb5b146108ff57806394cf795e1461093057600080fd5b806375dc7d8c146107935780637df73e27146107b3578063812db1be1461081857600080fd5b80635c975abb1161025e57806363c724f7116102075780636f760d6c116101e15780636f760d6c1461071c578063715018a614610749578063715bfe511461075e57600080fd5b806363c724f7146106ae57806365e17c9d146106ce5780636dbf2fa0146106fb57600080fd5b8063615f32ed11610238578063615f32ed1461063e578063628484ab1461065e578063629866b21461068e57600080fd5b80635c975abb146105bc5780635d334185146105e15780635fbbc0d21461060157600080fd5b80632ca3998d116102c05780634535b1131161029a5780634535b113146104d85780634b023cf8146104f85780635982fd201461051857600080fd5b80632ca3998d1461040f5780633f4ba83a1461048557806341f684f31461049a57600080fd5b806313cb3591116102f157806313cb3591146103705780632079fb9a146103aa5780632465e58e146103ef57600080fd5b8063014e95ba1461032057806308f496dd1461035057600080fd5b3661031b57610319610b96565b005b600080fd5b34801561032c57600080fd5b5061033661271081565b60405163ffffffff90911681526020015b60405180910390f35b34801561035c57600080fd5b5061031961036b366004614657565b610bd7565b34801561037c57600080fd5b50600e546103919067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610347565b3480156103b657600080fd5b506103ca6103c5366004614674565b610bed565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610347565b3480156103fb57600080fd5b5061031961040a366004614657565b610c49565b34801561041b57600080fd5b50604080518082018252600080825260209182015281518083018352600d546fffffffffffffffffffffffffffffffff8082168084527001000000000000000000000000000000009092048116928401928352845191825291519091169181019190915201610347565b34801561049157600080fd5b50610319610c98565b3480156104a657600080fd5b507ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b545b604051908152602001610347565b3480156104e457600080fd5b506103196104f3366004614770565b610d33565b34801561050457600080fd5b50610319610513366004614657565b610e72565b34801561052457600080fd5b506105af6040805160608101825260008082526020820181905291810191909152506040805160608101825260035463ffffffff81168252640100000000810473ffffffffffffffffffffffffffffffffffffffff1660208301527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169181019190915290565b60405161034791906147b0565b3480156105c857600080fd5b506105d1610ec1565b6040519015158152602001610347565b3480156105ed57600080fd5b506103196105fc3660046148e8565b610ef3565b34801561060d57600080fd5b5061061661109a565b6040805182518152602080840151908201529181015163ffffffff1690820152606001610347565b34801561064a57600080fd5b50610319610659366004614938565b6110ef565b34801561066a57600080fd5b506105d1610679366004614674565b600f6020526000908152604090205460ff1681565b34801561069a57600080fd5b506103196106a936600461498d565b61124a565b3480156106ba57600080fd5b506103196106c9366004614657565b61136f565b3480156106da57600080fd5b506001546103ca9073ffffffffffffffffffffffffffffffffffffffff1681565b61070e6107093660046149fe565b61140d565b604051610347929190614af5565b34801561072857600080fd5b5061073c610737366004614bc3565b611491565b6040516103479190614c69565b34801561075557600080fd5b5061031961166f565b34801561076a57600080fd5b5061077e610779366004614674565b611681565b60408051928352602083019190915201610347565b34801561079f57600080fd5b506104ca6107ae366004614674565b611714565b3480156107bf57600080fd5b506105d16107ce366004614657565b73ffffffffffffffffffffffffffffffffffffffff1660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205460ff1690565b34801561082457600080fd5b506108a160408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526009548152600a546020820152600b546fffffffffffffffffffffffffffffffff808216938301939093527001000000000000000000000000000000009004909116606082015290565b604080518251815260208084015190820152828201516fffffffffffffffffffffffffffffffff9081169282019290925260609283015190911691810191909152608001610347565b3480156108f657600080fd5b5061031961174f565b34801561090b57600080fd5b5060005462010000900473ffffffffffffffffffffffffffffffffffffffff166103ca565b34801561093c57600080fd5b506109456117ea565b6040516103479190614ca1565b34801561095e57600080fd5b50610319611878565b34801561097357600080fd5b506103ca610982366004614674565b60106020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156109b657600080fd5b506105d16109c5366004614657565b611883565b3480156109d657600080fd5b506109ea6109e5366004614cef565b611898565b6040516103479190614d64565b348015610a0357600080fd5b50610319610a12366004614de6565b611980565b348015610a2357600080fd5b50610a2c611b98565b6040516103479190614e2a565b610319610a47366004614657565b611c4e565b348015610a5857600080fd5b50610319611d85565b348015610a6d57600080fd5b50610319610a7c366004614657565b611e11565b348015610a8d57600080fd5b50610319610a9c366004614e9b565b611e24565b348015610aad57600080fd5b50610319610abc366004614657565b6120a1565b348015610acd57600080fd5b506002546103ca9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610afa57600080fd5b50610945610b09366004614bc3565b61213f565b348015610b1a57600080fd5b50610319610b29366004614f35565b612316565b348015610b3a57600080fd5b50610945610b49366004614f57565b61232c565b348015610b5a57600080fd5b50610945610b69366004614f98565b6124f9565b348015610b7a57600080fd5b50610319610b89366004614657565b6126c6565b61031961277a565b610b9e610ec1565b15610bd5576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b610bdf612920565b610bea6000826129a8565b50565b60007ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b8281548110610c2157610c21615032565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1692915050565b610c51612920565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610ca133611883565b80610cf5575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610d2b576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd5612a1c565b610d3b612920565b61271063ffffffff16816040015163ffffffff161115610dbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f666565207261746500000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b602081015181511115610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6665652072616e676500000000000000000000000000000000000000000000006044820152606401610db3565b8051600655602081015160075560400151600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091179055565b610e7a612920565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000610eee7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e55460ff1690565b905090565b600054610100900460ff1615808015610f135750600054600160ff909116105b80610f2d5750303b158015610f2d575060005460ff166001145b610fb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610db3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561101757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61102033612ab8565b611029826110ef565b61103283612ab8565b801561109557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6110c460405180606001604052806000815260200160008152602001600063ffffffff1681525090565b50604080516060810182526006548152600754602082015260085463ffffffff169181019190915290565b6110f7612920565b805173ffffffffffffffffffffffffffffffffffffffff16611175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b6520636f6e74726163740000000000000000000000000000000000006044820152606401610db3565b8060200151516001146111e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e637049647300000000000000000000000000000000000000000000000000006044820152606401610db3565b8051600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117815560208083015180518493926112449260059291019061457a565b50505050565b611252612920565b80516112ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f627269646765206d696e000000000000000000000000000000000000000000006044820152606401610db3565b6020810151815110611328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6272696467652072616e676500000000000000000000000000000000000000006044820152606401610db3565b80516009556020810151600a5560408101516060909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600b55565b61137833611883565b806113cc575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611402576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bea600082612af9565b60006060611419612920565b8573ffffffffffffffffffffffffffffffffffffffff16858585604051611441929190615061565b60006040518083038185875af1925050503d806000811461147e576040519150601f19603f3d011682016040523d82523d6000602084013e611483565b606091505b509150915094509492505050565b606061149b610b96565b67ffffffffffffffff84166000908152600f602052604090205460ff161561151f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f737263206e6f6e636500000000000000000000000000000000000000000000006044820152606401610db3565b67ffffffffffffffff84166000908152600f6020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611569612b6d565b905061157781868686612c73565b604082015261158584612d2b565b91506115c6816040015180516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152611666958086019391929083018282801561165857602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116116295790505b50505050508152505061316d565b50509392505050565b611677612920565b610bd56000612ab8565b6040805160608082018352600654825260075460208084019190915260085463ffffffff168385015283516080810185526009548152600a5491810191909152600b546fffffffffffffffffffffffffffffffff80821695830195909552700100000000000000000000000000000000900490931690830152600091829161170b918591906132f8565b91509150915091565b604080516060810182526006548152600754602082015260085463ffffffff169181019190915260009061174990839061338e565b92915050565b61175833611883565b806117ac575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6117e2576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd56133c8565b60607ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b80548060200260200160405190810160405280929190818152602001828054801561186e57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611843575b5050505050905090565b610bd53360006129a8565b600061188e82613441565b5460ff1692915050565b6040805160008152602081019091526060908267ffffffffffffffff8111156118c3576118c361468d565b6040519080825280602002602001820160405280156118f657816020015b60608152602001906001900390816118e15790505b50915060005b83811015611978576119533086868481811061191a5761191a615032565b905060200281019061192c91906150b3565b8560405160200161193f93929190615118565b6040516020818303038152906040526134ac565b83828151811061196557611965615032565b60209081029190910101526001016118fc565b505092915050565b611988612920565b602081015173ffffffffffffffffffffffffffffffffffffffff16611a09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f62726964676520616464726573730000000000000000000000000000000000006044820152606401610db3565b805163ffffffff16600003611a7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f62726964676520636861696e20696400000000000000000000000000000000006044820152606401610db3565b604081015167ffffffffffffffff1615611af0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f627269646765206e6f6e636500000000000000000000000000000000000000006044820152606401610db3565b805160038054602084015160409094015167ffffffffffffffff1678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff909516640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921663ffffffff909416939093171792909216179055565b6040805180820190915260008152606060208201526040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152939492938386019390929190830182828015611c4057602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411611c115790505b505050505081525050905090565b611c56610b96565b73ffffffffffffffffffffffffffffffffffffffff8116611c745750335b611c7d346134d8565b6000611c87612b6d565b9050611cbf8160405180604001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020013481525060016136bf565b60408201819052611d019080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526110959580860193919290830182828015611658576000918252602091829020805460ff16845290820283019290916001910180841161162957905050505050508152505061316d565b611d8d610b96565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152610bea9580860193919290830182828015611658576000918252602091829020805460ff16845290820283019290916001910180841161162957905050505050508152505061316d565b611e19612920565b610bea8160006129a8565b805160017ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b54611e56911c600161513f565b811015611ebf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f71756f72756d00000000000000000000000000000000000000000000000000006044820152606401610db3565b6001811115611fbe576000611ed56001836150a0565b905060005b81811015611fbb5783611eee82600161513f565b81518110611efe57611efe615032565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16848281518110611f2e57611f2e615032565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611fb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f417363656e64696e67204f7264657200000000000000000000000000000000006044820152606401610db3565b600101611eda565b50505b7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b60005b8281101561124457816000858381518110611fff57611fff615032565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff16612099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c6964207369676e65720000000000000000000000000000000000006044820152606401610db3565b600101611fe2565b6120aa33611883565b806120fe575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612134576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bea816000612af9565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff871683850152925190926000916121a491849160029189910161518d565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156121d6576121d661468d565b6040519080825280602002602001820160405280156121ff578160200160208202803683370190505b50925060005b845181101561230c5760018286838151811061222357612223615032565b60200260200101516000015187848151811061224157612241615032565b60200260200101516020015188858151811061225f5761225f615032565b602002602001015160400151604051600081526020016040526040516122a1949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156122c3573d6000803e3d6000fd5b505050602060405103518482815181106122df576122df615032565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612205565b5050509392505050565b61231e610b96565b612328828261382d565b5050565b60408051606080820183526003805463ffffffff81168452640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208085019190915267ffffffffffffffff88168486015293519193600092612391928592909189910161520b565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156123c3576123c361468d565b6040519080825280602002602001820160405280156123ec578160200160208202803683370190505b50925060005b845181101561230c5760018286838151811061241057612410615032565b60200260200101516000015187848151811061242e5761242e615032565b60200260200101516020015188858151811061244c5761244c615032565b6020026020010151604001516040516000815260200160405260405161248e949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156124b0573d6000803e3d6000fd5b505050602060405103518482815181106124cc576124cc615032565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016123f2565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff8716838501529251909260009161255e918491600191899101615268565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156125905761259061468d565b6040519080825280602002602001820160405280156125b9578160200160208202803683370190505b50925060005b845181101561230c576001828683815181106125dd576125dd615032565b6020026020010151600001518784815181106125fb576125fb615032565b60200260200101516020015188858151811061261957612619615032565b6020026020010151604001516040516000815260200160405260405161265b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561267d573d6000803e3d6000fd5b5050506020604051035184828151811061269957612699615032565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016125bf565b6126ce612920565b73ffffffffffffffffffffffffffffffffffffffff8116612771576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610db3565b610bea81612ab8565b612782610b96565b600061278c612b6d565b60025490915073ffffffffffffffffffffffffffffffffffffffff16338114612813576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db39060208082526004908201527f73796e6300000000000000000000000000000000000000000000000000000000604082015260600190565b61281c346134d8565b34826040015160000181815161283291906152f0565b6fffffffffffffffffffffffffffffffff169052506040820151602001805134919061285f9083906152f0565b6fffffffffffffffffffffffffffffffff1690525060408201516128b49080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006128be613b5f565b90508173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f6a28c316db1c85974981164e2be540ab36fb82b391d0dfda369f948d1474de173460405161291391815260200190565b60405180910390a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff62010000909104163314610bd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610db3565b6129b3826000613ba8565b6129be816001613ba8565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b612a24613c45565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16612ae081611883565b15612af057612af08160006129a8565b61232882613c83565b612b04826000613d01565b612b0f816001613d01565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f9d188613a1a9a2ea26521bec252487f1739a344d8ffe6ef61cd7bca567d8f3d160405160405180910390a35050565b612bd16040805160c08101825260006060808301828152608080850184905260a08501849052908452845190810185528281526020808201849052818601849052918101839052818401528351808501855282815290810191909152909182015290565b604080516080810182526009548152600a54602080830191909152600b546fffffffffffffffffffffffffffffffff80821684860152700100000000000000000000000000000000918290048116606080860191909152868401949094528451938401855260065484526007548484015260085463ffffffff168486015292855283518085018552600d54808516825291909104909216908201529082015290565b6040805180820190915260008082526020820152612c92848484613ebc565b602083015160408601518051612ca9908390615319565b6fffffffffffffffffffffffffffffffff16905250825160208085015160405190815273ffffffffffffffffffffffffffffffffffffffff9092169167ffffffffffffffff8716917fca798eef187f833f790884379ed453edfc01901535dc3083866f8446dc25f0f8910160405180910390a35060408401515b949350505050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526060956000959493818601939091830182828015612dc057602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612d915790505b5050505050815250509050600081600001519050600080612de5848760200151613eca565b915091506000805b835181101561316157828181518110612e0857612e08615032565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e09818858381518110612e5257612e52615032565b6020026020010151868481518110612e6c57612e6c615032565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af1158015612ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f159190615342565b838281518110612f2757612f27615032565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff1660106000858481518110612f8757612f87615032565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614613031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401610db3565b87600001516010600085848151811061304c5761304c615032565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508381815181106130c4576130c4615032565b602002602001015160ff16886000015173ffffffffffffffffffffffffffffffffffffffff167f4833244c0517cc1688428ff8842d0c253c9cea94b95f61d91a680203b55ebf0185848151811061311d5761311d615032565b6020026020010151856040516131519291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a3600101612ded565b50909695505050505050565b60025460009073ffffffffffffffffffffffffffffffffffffffff16806131f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f73796e63207a65726f00000000000000000000000000000000000000000000006044820152606401610db3565b825173ffffffffffffffffffffffffffffffffffffffff821631925060005b8460200151518110156132d6578173ffffffffffffffffffffffffffffffffffffffff1663ddd5e1b28660200151838151811061324e5761324e615032565b6020026020010151856040518363ffffffff1660e01b815260040161329892919060ff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156132b257600080fd5b505af11580156132c6573d6000803e3d6000fd5b50506001909201915061320f9050565b50612d238373ffffffffffffffffffffffffffffffffffffffff8416316150a0565b6000806133058584613ee3565b61330f858561338e565b905080851161337a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401610db3565b61338481866150a0565b9150935093915050565b6040810151815161271063ffffffff909216840291909104908110156133b2575080515b8160200151811115611749575060200151919050565b6133d0610b96565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833612a8e565b6040805173ffffffffffffffffffffffffffffffffffffffff831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b91810191909152600090611749906060016040516020818303038152906040528051906020012090565b60606134d1838360405180606001604052806027815260200161548860279139613fbc565b9392505050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526000958086019391929083018282801561356957602002820191906000526020600020906000905b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161353a5790505b505050919092525050815191925060009050806135868486614041565b9150915060005b82518110156136b7578373ffffffffffffffffffffffffffffffffffffffff16636366ebe38383815181106135c4576135c4615032565b60200260200101516fffffffffffffffffffffffffffffffff168584815181106135f0576135f0615032565b602002602001015185858151811061360a5761360a615032565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260ff90921660048301526fffffffffffffffffffffffffffffffff166024820152306044820152600060648201819052608482015260a4016000604051808303818588803b15801561369257600080fd5b505af11580156136a6573d6000803e3d6000fd5b50506001909301925061358d915050565b505050505050565b604080518082019091526000808252602082015260006136e784602001518660200151613ee3565b821561377a576136ff8460200151866000015161338e565b90508084602001511161376e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401610db3565b60208401805182900390525b6020840151604086015180516137919083906152f0565b6fffffffffffffffffffffffffffffffff1690525060006137b0613b5f565b9050846000015173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f87c8e141595387353b9f5800de2510b7678d07b38c7e01c29ab619d7938e6396876020015185604051613816929190918252602082015260400190565b60405180910390a350505060408301519392505050565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff16806138b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401610db3565b600082815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556004805482517f83453945000000000000000000000000000000000000000000000000000000008152925173ffffffffffffffffffffffffffffffffffffffff909116949385936383453945938181019391829003018187875af115801561395c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613980919061535b565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b81526004016139ba91815260200190565b60e060405180830381865afa1580156139d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139fb9190615378565b606001516040517f0ad58d2f000000000000000000000000000000000000000000000000000000008152600481018790526024810186905273ffffffffffffffffffffffffffffffffffffffff85811660448301529192504791841690630ad58d2f90606401600060405180830381600087803b158015613a7b57600080fd5b505af1158015613a8f573d6000803e3d6000fd5b50505050818147613aa091906150a0565b14613b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401610db3565b613b118483614129565b5084868573ffffffffffffffffffffffffffffffffffffffff167f56938cd8bd3b7e9e03d3414d2307365bc79aa14190fc2b22e7119ad2ba26c48160405160405180910390a4505050505050565b600e805460009167ffffffffffffffff9091169082613b7d83615402565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905090565b73ffffffffffffffffffffffffffffffffffffffff821615612328576000613bcf83613441565b805490915082151560ff909116151503613c15576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80548215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790555050565b613c4d610ec1565b610bd5576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b73ffffffffffffffffffffffffffffffffffffffff8216156123285773ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205481151560ff909116151503613da3576040517fd4be6f0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215801591909117909155613e92577ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b80546001810182556000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555050565b6123287ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b83614339565b611095610a9c84848461213f565b606080613ed78484614041565b915091505b9250929050565b8051821015613f4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d696e696d756d000000000000000000000000000000000000000000000000006044820152606401610db3565b8181602001511015612328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d6178696d756d000000000000000000000000000000000000000000000000006044820152606401610db3565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051613fe69190615429565b600060405180830381855af49150503d8060008114614021576040519150601f19603f3d011682016040523d82523d6000602084013e614026565b606091505b50915091506140378683838761449b565b9695505050505050565b6060808360200151516001146140b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f64656661756c74206e63704964000000000000000000000000000000000000006044820152606401610db3565b602084015160408051600180825281830190925291935081602001602082028036833701905050905082816000815181106140f0576140f0615032565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff16815250509250929050565b600081471015614195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6661696c2073656e642076616c756500000000000000000000000000000000006044820152606401610db3565b60405173ffffffffffffffffffffffffffffffffffffffff8416908390600081818185875af1925050503d80600081146141eb576040519150601f19603f3d011682016040523d82523d6000602084013e6141f0565b606091505b50508091505080611749578273ffffffffffffffffffffffffffffffffffffffff167f7a8da3fbf14e43fbfd79d8ce7ab913a13000dbbd248e9442988476e9e4b94cd88360405161424391815260200190565b60405180910390a26000805462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d80600081146142c2576040519150601f19603f3d011682016040523d82523d6000602084013e6142c7565b606091505b5050905080614332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6661696c20616d6f756e742063617463680000000000000000000000000000006044820152606401610db3565b5092915050565b815460005b818110156112445783818154811061435857614358615032565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff9081169084160361449357836143906001846150a0565b815481106143a0576143a0615032565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168482815481106143dd576143dd615032565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508380548061443557614435615445565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b60010161433e565b6060831561453157825160000361452a5773ffffffffffffffffffffffffffffffffffffffff85163b61452a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610db3565b5081612d23565b612d2383838151156145465781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db39190615474565b82805482825590600052602060002090601f016020900481019282156146105791602002820160005b838211156145e157835183826101000a81548160ff021916908360ff16021790555092602001926001016020816000010492830192600103026145a3565b801561460e5782816101000a81549060ff02191690556001016020816000010492830192600103026145e1565b505b5061461c929150614620565b5090565b5b8082111561461c5760008155600101614621565b73ffffffffffffffffffffffffffffffffffffffff81168114610bea57600080fd5b60006020828403121561466957600080fd5b81356134d181614635565b60006020828403121561468657600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156146df576146df61468d565b60405290565b6040805190810167ffffffffffffffff811182821017156146df576146df61468d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561474f5761474f61468d565b604052919050565b803563ffffffff8116811461476b57600080fd5b919050565b60006060828403121561478257600080fd5b61478a6146bc565b82358152602083013560208201526147a460408401614757565b60408201529392505050565b815163ffffffff16815260208083015173ffffffffffffffffffffffffffffffffffffffff169082015260408083015167ffffffffffffffff169082015260608101611749565b600067ffffffffffffffff8211156148115761481161468d565b5060051b60200190565b803560ff8116811461476b57600080fd5b60006040828403121561483e57600080fd5b6148466146e5565b9050813561485381614635565b815260208281013567ffffffffffffffff81111561487057600080fd5b8301601f8101851361488157600080fd5b803561489461488f826147f7565b614708565b81815260059190911b820183019083810190878311156148b357600080fd5b928401925b828410156148d8576148c98461481b565b825292840192908401906148b8565b8085870152505050505092915050565b600080604083850312156148fb57600080fd5b823561490681614635565b9150602083013567ffffffffffffffff81111561492257600080fd5b61492e8582860161482c565b9150509250929050565b60006020828403121561494a57600080fd5b813567ffffffffffffffff81111561496157600080fd5b612d238482850161482c565b80356fffffffffffffffffffffffffffffffff8116811461476b57600080fd5b60006080828403121561499f57600080fd5b6040516080810181811067ffffffffffffffff821117156149c2576149c261468d565b806040525082358152602083013560208201526149e16040840161496d565b60408201526149f26060840161496d565b60608201529392505050565b60008060008060608587031215614a1457600080fd5b8435614a1f81614635565b935060208501359250604085013567ffffffffffffffff80821115614a4357600080fd5b818701915087601f830112614a5757600080fd5b813581811115614a6657600080fd5b886020828501011115614a7857600080fd5b95989497505060200194505050565b60005b83811015614aa2578181015183820152602001614a8a565b50506000910152565b60008151808452614ac3816020860160208601614a87565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8215158152604060208201526000612d236040830184614aab565b803567ffffffffffffffff8116811461476b57600080fd5b600082601f830112614b3957600080fd5b81356020614b4961488f836147f7565b82815260609283028501820192828201919087851115614b6857600080fd5b8387015b85811015614bb65781818a031215614b845760008081fd5b614b8c6146bc565b614b958261481b565b81528186013586820152604080830135908201528452928401928101614b6c565b5090979650505050505050565b60008060008385036080811215614bd957600080fd5b614be285614b10565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082011215614c1457600080fd5b50614c1d6146e5565b6020850135614c2b81614635565b8152604085013560208201529150606084013567ffffffffffffffff811115614c5357600080fd5b614c5f86828701614b28565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561316157835183529284019291840191600101614c85565b6020808252825182820181905260009190848201906040850190845b8181101561316157835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614cbd565b60008060208385031215614d0257600080fd5b823567ffffffffffffffff80821115614d1a57600080fd5b818501915085601f830112614d2e57600080fd5b813581811115614d3d57600080fd5b8660208260051b8501011115614d5257600080fd5b60209290920196919550909350505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614dd9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452614dc7858351614aab565b94509285019290850190600101614d8d565b5092979650505050505050565b600060608284031215614df857600080fd5b614e006146bc565b614e0983614757565b81526020830135614e1981614635565b60208201526147a460408401614b10565b6020808252825173ffffffffffffffffffffffffffffffffffffffff16828201528281015160408084015280516060840181905260009291820190839060808601905b80831015614e9057835160ff168252928401926001929092019190840190614e6d565b509695505050505050565b60006020808385031215614eae57600080fd5b823567ffffffffffffffff811115614ec557600080fd5b8301601f81018513614ed657600080fd5b8035614ee461488f826147f7565b81815260059190911b82018301908381019087831115614f0357600080fd5b928401925b82841015614f2a578335614f1b81614635565b82529284019290840190614f08565b979650505050505050565b60008060408385031215614f4857600080fd5b50508035926020909101359150565b600080600060608486031215614f6c57600080fd5b614f7584614b10565b925060208401359150604084013567ffffffffffffffff811115614c5357600080fd5b600080600083850360a0811215614fae57600080fd5b614fb785614b10565b935060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082011215614fe957600080fd5b50614ff26146bc565b602085013561500081614635565b815260408581013560208301526060860135908201529150608084013567ffffffffffffffff811115614c5357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561174957611749615071565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126150e857600080fd5b83018035915067ffffffffffffffff82111561510357600080fd5b602001915036819003821315613edc57600080fd5b828482376000838201600081528351615135818360208801614a87565b0195945050505050565b8082018082111561174957611749615071565b60048110615189577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260c081016151dc6060830185615152565b73ffffffffffffffffffffffffffffffffffffffff8351166080830152602083015160a0830152949350505050565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260a0810161525a6060830185615152565b826080830152949350505050565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260e081016152b76060830185615152565b73ffffffffffffffffffffffffffffffffffffffff8351166080830152602083015160a0830152604083015160c0830152949350505050565b6fffffffffffffffffffffffffffffffff81811683821601908082111561433257614332615071565b6fffffffffffffffffffffffffffffffff82811682821603908082111561433257614332615071565b60006020828403121561535457600080fd5b5051919050565b60006020828403121561536d57600080fd5b81516134d181614635565b600060e0828403121561538a57600080fd5b60405160e0810181811067ffffffffffffffff821117156153ad576153ad61468d565b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301516153f681614635565b60c08201529392505050565b600067ffffffffffffffff80831681810361541f5761541f615071565b6001019392505050565b6000825161543b818460208701614a87565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6020815260006134d16020830184614aab56fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fdb6ba83f728e5392faff07831cb2795776710580c3d03aa2c41f045bbc8d35864736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007d76ae60dcc2fdb57d3924024e2ad940b76ef81f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000006af09e1a3c886dd8560bf4cabd65db16ea2724d8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000029
-----Decoded View---------------
Arg [0] : owner (address): 0x7D76Ae60dcc2FdB57d3924024E2Ad940B76Ef81f
Arg [1] : _stakingInfo (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000007d76ae60dcc2fdb57d3924024e2ad940b76ef81f
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000006af09e1a3c886dd8560bf4cabd65db16ea2724d8
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000029
Deployed Bytecode Sourcemap
309:7419:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1917:19:26;:17;:19::i;:::-;309:7419:5;;;;;260:39:4;;;;;;;;;;;;294:5;260:39;;;;;188:10:31;176:23;;;158:42;;146:2;131:18;260:39:4;;;;;;;;1953:107:25;;;;;;;;;;-1:-1:-1;1953:107:25;;;;;:::i;:::-;;:::i;561:33:4:-;;;;;;;;;;-1:-1:-1;561:33:4;;;;;;;;;;;796:18:31;784:31;;;766:50;;754:2;739:18;561:33:4;622:200:31;1959:124:27;;;;;;;;;;-1:-1:-1;1959:124:27;;;;;:::i;:::-;;:::i;:::-;;;1188:42:31;1176:55;;;1158:74;;1146:2;1131:18;1959:124:27;1012:226:31;982:115:4;;;;;;;;;;-1:-1:-1;982:115:4;;;;;:::i;:::-;;:::i;2739:97::-;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;2816:17:4;;;;;;;2823:10;2816:17;;;;;;;;;;;;;;;;;;;;2739:97;;1496:41:31;;;1579:24;;1575:33;;;1553:20;;;1546:63;;;;1416:18;2739:97:4;1243:372:31;2355:70:25;;;;;;;;;;;;;:::i;2089:117:27:-;;;;;;;;;;-1:-1:-1;1806:66:27;2161:38;2089:117;;;1766:25:31;;;1754:2;1739:18;2089:117:27;1620:177:31;1725:238:4;;;;;;;;;;-1:-1:-1;1725:238:4;;;;;:::i;:::-;;:::i;866:111::-;;;;;;;;;;-1:-1:-1;866:111:4;;;;;:::i;:::-;;:::i;2280:121::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;2377:21:4;;;;;;;;2384:14;2377:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;2280:121;;;;;;;;:::i;2293:86:26:-;;;;;;;;;;;;;:::i;:::-;;;4196:14:31;;4189:22;4171:41;;4159:2;4144:18;2293:86:26;4031:187:31;562:249:5;;;;;;;;;;-1:-1:-1;562:249:5;;;;;:::i;:::-;;:::i;2512:95:4:-;;;;;;;;;;;;;:::i;:::-;;;;6325:13:31;;6307:32;;6395:4;6383:17;;;6377:24;6355:20;;;6348:54;6450:17;;;6444:24;6470:10;6440:41;6418:20;;;6411:71;6295:2;6280:18;2512:95:4;6107:381:31;1454:265:4;;;;;;;;;;-1:-1:-1;1454:265:4;;;;;:::i;:::-;;:::i;600:76::-;;;;;;;;;;-1:-1:-1;600:76:4;;;;;:::i;:::-;;;;;;;;;;;;;;;;1969:305;;;;;;;;;;-1:-1:-1;1969:305:4;;;;;:::i;:::-;;:::i;2510:124:27:-;;;;;;;;;;-1:-1:-1;2510:124:27;;;;;:::i;:::-;;:::i;305:25:4:-;;;;;;;;;;-1:-1:-1;305:25:4;;;;;;;;1601:229:25;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;1313:595:5:-;;;;;;;;;;-1:-1:-1;1313:595:5;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1815:101:23:-;;;;;;;;;;;;;:::i;2842:213:4:-;;;;;;;;;;-1:-1:-1;2842:213:4;;;;;:::i;:::-;;:::i;:::-;;;;12347:25:31;;;12403:2;12388:18;;12381:34;;;;12320:18;2842:213:4;12173:248:31;3060:126:4;;;;;;;;;;-1:-1:-1;3060:126:4;;;;;:::i;:::-;;:::i;2367:137:27:-;;;;;;;;;;-1:-1:-1;2367:137:27;;;;;:::i;:::-;2454:43;;2431:4;2454:43;;;1806:66;2454:43;;;;;;;;;2367:137;2612:122:4;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2706:25:4;;;;;;;;2713:18;2706:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2612:122;;;;;12663:13:31;;12645:32;;12733:4;12721:17;;;12715:24;12693:20;;;12686:54;12775:17;;;12769:24;12812:34;12884:21;;;12862:20;;;12855:51;;;;12966:4;12954:17;;;12948:24;12944:33;;;12922:20;;;12915:63;;;;12632:3;12617:19;2612:122:4;12426:558:31;2283:66:25;;;;;;;;;;;;;:::i;1192:85:23:-;;;;;;;;;;-1:-1:-1;1238:7:23;1264:6;;;;;;1192:85;;2212:149:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;2180:97:25:-;;;;;;;;;;;;;:::i;682:83:4:-;;;;;;;;;;-1:-1:-1;682:83:4;;;;;:::i;:::-;;;;;;;;;;;;;;;;1836:111:25;;;;;;;;;;-1:-1:-1;1836:111:25;;;;;:::i;:::-;;:::i;1203:484:22:-;;;;;;;;;;-1:-1:-1;1203:484:22;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1103:346:4:-;;;;;;;;;;-1:-1:-1;1103:346:4;;;;;:::i;:::-;;:::i;2406:101::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;880:427:5:-;;;;;;:::i;:::-;;:::i;2068:95::-;;;;;;;;;;;;;:::i;2066:108:25:-;;;;;;;;;;-1:-1:-1;2066:108:25;;;;;:::i;:::-;;:::i;2771:725:27:-;;;;;;;;;;-1:-1:-1;2771:725:27;;;;;:::i;:::-;;:::i;2640:125::-;;;;;;;;;;-1:-1:-1;2640:125:27;;;;;:::i;:::-;;:::i;336:26:4:-;;;;;;;;;;-1:-1:-1;336:26:4;;;;;;;;4007:589;;;;;;;;;;-1:-1:-1;4007:589:4;;;;;:::i;:::-;;:::i;1914:148:5:-;;;;;;;;;;-1:-1:-1;1914:148:5;;;;;:::i;:::-;;:::i;4822:551:4:-;;;;;;;;;;-1:-1:-1;4822:551:4;;;;;:::i;:::-;;:::i;3192:589::-;;;;;;;;;;-1:-1:-1;3192:589:4;;;;;:::i;:::-;;:::i;2065:198:23:-;;;;;;;;;;-1:-1:-1;2065:198:23;;;;;:::i;:::-;;:::i;2169:549:5:-;;;:::i;2447:104:26:-;2512:8;:6;:8::i;:::-;2508:36;;;2529:15;;;;;;;;;;;;;;2508:36;2447:104::o;1953:107:25:-;1085:13:23;:11;:13::i;:::-;2016:37:25::1;2043:1;2047:5;2016:18;:37::i;:::-;1953:107:::0;:::o;1959:124:27:-;2012:7;1806:66;2070:5;2038:38;;;;;;;;:::i;:::-;;;;;;;;;;;;;;1959:124;-1:-1:-1;;1959:124:27:o;982:115:4:-;1085:13:23;:11;:13::i;:::-;1064:11:4::1;:26:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;982:115::o;2355:70:25:-;1225:22;734:10:2;1836:111:25;:::i;1225:22::-;:49;;;-1:-1:-1;1238:7:23;1264:6;;;;;;1251:23:25;;734:10:2;1251:23:25;;;1225:49;1219:76;;1284:11;;;;;;;;;;;;;;1219:76;2408:10:::1;:8;:10::i;1725:238:4:-:0;1085:13:23;:11;:13::i;:::-;294:5:4::1;1820:27;;:10;:15;;;:27;;;;1812:48;;;::::0;::::1;::::0;;19639:2:31;1812:48:4::1;::::0;::::1;19621:21:31::0;19678:1;19658:18;;;19651:29;19716:10;19696:18;;;19689:38;19744:18;;1812:48:4::1;;;;;;;;;1896:14;::::0;::::1;::::0;1878;;:32:::1;;1870:54;;;::::0;::::1;::::0;;19975:2:31;1870:54:4::1;::::0;::::1;19957:21:31::0;20014:1;19994:18;;;19987:29;20052:11;20032:18;;;20025:39;20081:18;;1870:54:4::1;19773:332:31::0;1870:54:4::1;1934:22:::0;;:9:::1;:22:::0;::::1;::::0;::::1;::::0;;;::::1;;::::0;;;;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;1725:238::o;866:111::-;1085:13:23;:11;:13::i;:::-;946:10:4::1;:24:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;866:111::o;2293:86:26:-;2340:4;2363:9;814:66;951:47;;;;887:118;2363:9;2356:16;;2293:86;:::o;562:249:5:-;3267:19:20;3290:13;;;;;;3289:14;;3335:34;;;;-1:-1:-1;3353:12:20;;3368:1;3353:12;;;;:16;3335:34;3334:108;;;-1:-1:-1;3414:4:20;1713:19:1;:23;;;3375:66:20;;-1:-1:-1;3424:12:20;;;;;:17;3375:66;3313:201;;;;;;;20312:2:31;3313:201:20;;;20294:21:31;20351:2;20331:18;;;20324:30;20390:34;20370:18;;;20363:62;20461:16;20441:18;;;20434:44;20495:19;;3313:201:20;20110:410:31;3313:201:20;3524:12;:16;;;;3539:1;3524:16;;;3550:65;;;;3584:13;:20;;;;;;;;3550:65;701:30:5::1;720:10;701:18;:30::i;:::-;741:28;756:12;741:14;:28::i;:::-;779:25;798:5;779:18;:25::i;:::-;3639:14:20::0;3635:99;;;3685:5;3669:21;;;;;;3709:14;;-1:-1:-1;20677:36:31;;3709:14:20;;20665:2:31;20650:18;3709:14:20;;;;;;;3635:99;3257:483;562:249:5;;:::o;2512:95:4:-;2568:16;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;2568:16:4;-1:-1:-1;2588:16:4;;;;;;;;2595:9;2588:16;;;;;;;;;;;;;;;;;;;;;2512:95::o;1454:265::-;1085:13:23;:11;:13::i;:::-;1555:27:4;;:41:::1;;1547:68;;;::::0;::::1;::::0;;20926:2:31;1547:68:4::1;::::0;::::1;20908:21:31::0;20965:2;20945:18;;;20938:30;21004:16;20984:18;;;20977:44;21038:18;;1547:68:4::1;20724:338:31::0;1547:68:4::1;1633:12;:19;;;:26;1663:1;1633:31;1625:50;;;::::0;::::1;::::0;;21269:2:31;1625:50:4::1;::::0;::::1;21251:21:31::0;21308:1;21288:18;;;21281:29;21346:8;21326:18;;;21319:36;21372:18;;1625:50:4::1;21067:329:31::0;1625:50:4::1;1686:26:::0;;:11:::1;:26:::0;;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;:11;:26:::1;::::0;;;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;;1454:265:4:o;1969:305::-;1085:13:23;:11;:13::i;:::-;2091:23:4;;2083:50:::1;;;::::0;::::1;::::0;;21603:2:31;2083:50:4::1;::::0;::::1;21585:21:31::0;21642:2;21622:18;;;21615:30;21681:12;21661:18;;;21654:40;21711:18;;2083:50:4::1;21401:334:31::0;2083:50:4::1;2177:23;::::0;::::1;::::0;2151;;:49:::1;2143:74;;;::::0;::::1;::::0;;21942:2:31;2143:74:4::1;::::0;::::1;21924:21:31::0;21981:2;21961:18;;;21954:30;22020:14;22000:18;;;21993:42;22052:18;;2143:74:4::1;21740:336:31::0;2143:74:4::1;2227:40:::0;;:18:::1;:40:::0;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;;::::0;;1969:305::o;2510:124:27:-;1225:22:25;734:10:2;1836:111:25;:::i;1225:22::-;:49;;;-1:-1:-1;1238:7:23;1264:6;;;;;;1251:23:25;;734:10:2;1251:23:25;;;1225:49;1219:76;;1284:11;;;;;;;;;;;;;;1219:76;2588:39:27::1;2616:1;2620:6;2588:19;:39::i;1601:229:25:-:0;1738:12;1752:23;1085:13:23;:11;:13::i;:::-;1794:2:25::1;:7;;1810:5;1818:4;;1794:29;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1787:36;;;;1601:229:::0;;;;;;;:::o;1313:595:5:-;1481:30;1917:19:26;:17;:19::i;:::-;1532:24:5::1;::::0;::::1;;::::0;;;:14:::1;:24;::::0;;;;;::::1;;1531:25;1523:47;;;::::0;::::1;::::0;;22559:2:31;1523:47:5::1;::::0;::::1;22541:21:31::0;22598:1;22578:18;;;22571:29;22636:11;22616:18;;;22609:39;22665:18;;1523:47:5::1;22357:332:31::0;1523:47:5::1;1580:24;::::0;::::1;;::::0;;;:14:::1;:24;::::0;;;;:31;;;::::1;1607:4;1580:31;::::0;;1655:20:::1;:18;:20::i;:::-;1622:53;;1708:58;1730:8;1740;1750:9;1761:4;1708:21;:58::i;:::-;1686:19;::::0;::::1;:80:::0;1792:26:::1;1808:9:::0;1792:15:::1;:26::i;:::-;1776:42;;1829:37;1846:8;:19;;;6000:23:4::0;;;;;;;;;;;;;;;;:10;:23;5926:104;1829:37:5::1;1876:25;::::0;;;;::::1;::::0;;1889:11:::1;1876:25:::0;;::::1;;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;;::::1;::::0;;;::::1;::::0;;;;;::::1;::::0;;;::::1;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;;::::1;::::0;::::1;;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;;;;;;;;;;;;;::::0;::::1;:12;:25::i;:::-;;1513:395;1313:595:::0;;;;;:::o;1815:101:23:-;1085:13;:11;:13::i;:::-;1879:30:::1;1906:1;1879:18;:30::i;2842:213:4:-:0;2984:64;;;;;;;;;3018:9;2984:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;3029:18;2984:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2924:22;;;;2984:64;;3010:6;;2984:64;:25;:64::i;:::-;2977:71;;;;2842:213;;;:::o;3060:126::-;3152:27;;;;;;;;3169:9;3152:27;;;;;;;;;;;;;;;;;;;;3116:17;;3152:27;;3161:6;;3152:8;:27::i;:::-;3145:34;3060:126;-1:-1:-1;;3060:126:4:o;2283:66:25:-;1225:22;734:10:2;1836:111:25;:::i;1225:22::-;:49;;;-1:-1:-1;1238:7:23;1264:6;;;;;;1251:23:25;;734:10:2;1251:23:25;;;1225:49;1219:76;;1284:11;;;;;;;;;;;;;;1219:76;2334:8:::1;:6;:8::i;2212:149:27:-:0;2255:16;1806:66;2316:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2212:149;:::o;2180:97:25:-;2226:44;734:10:2;2267:1:25;2226:18;:44::i;1836:111::-;1890:4;1913:21;1928:5;1913:14;:21::i;:::-;:27;;;;1836:111;-1:-1:-1;;1836:111:25:o;1203:484:22:-;1369:12;;;1305:20;1369:12;;;;;;;;1271:22;;1480:4;1468:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1458:34;;1507:9;1502:155;1522:15;;;1502:155;;;1571:75;1608:4;1628;;1633:1;1628:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1637;1615:30;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1571:28;:75::i;:::-;1558:7;1566:1;1558:10;;;;;;;;:::i;:::-;;;;;;;;;;:88;1539:3;;1502:155;;;;1666:14;1203:484;;;;:::o;1103:346:4:-;1085:13:23;:11;:13::i;:::-;1217:22:4::1;::::0;::::1;::::0;:36:::1;;1209:63;;;::::0;::::1;::::0;;24584:2:31;1209:63:4::1;::::0;::::1;24566:21:31::0;24623:2;24603:18;;;24596:30;24662:16;24642:18;;;24635:44;24696:18;;1209:63:4::1;24382:338:31::0;1209:63:4::1;1290:23:::0;;:28:::1;;:23;:28:::0;1282:56:::1;;;::::0;::::1;::::0;;24927:2:31;1282:56:4::1;::::0;::::1;24909:21:31::0;24966:2;24946:18;;;24939:30;25005:17;24985:18;;;24978:45;25040:18;;1282:56:4::1;24725:339:31::0;1282:56:4::1;1356:21;::::0;::::1;::::0;:26:::1;;::::0;1348:51:::1;;;::::0;::::1;::::0;;25271:2:31;1348:51:4::1;::::0;::::1;25253:21:31::0;25310:2;25290:18;;;25283:30;25349:14;25329:18;;;25322:42;25381:18;;1348:51:4::1;25069:336:31::0;1348:51:4::1;1410:32:::0;;:14:::1;:32:::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;;::::1;;::::0;;1103:346::o;2406:101::-;-1:-1:-1;;;;;;;;;;;;;;;;;2486:18:4;;;;;;;;2493:11;2486:18;;;;;;;;;;;;;;;;;;;;;;;;;;;2493:11;;2486:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2406:101;:::o;880:427:5:-;1917:19:26;:17;:19::i;:::-;966:21:5::1;::::0;::::1;963:46;;-1:-1:-1::0;999:10:5::1;963:46;1020:17;1027:9;1020:6;:17::i;:::-;1048:30;1081:20;:18;:20::i;:::-;1048:53;;1133:84;1156:8;1166:44;;;;;;;;1191:7;1166:44;;;;;;1200:9;1166:44;;::::0;1212:4:::1;1133:22;:84::i;:::-;1111:19;::::0;::::1;:106:::0;;;1228:37:::1;::::0;6000:23:4;;;;;;;;;;;;;;;;:10;:23;5926:104;1228:37:5::1;1275:25;::::0;;;;::::1;::::0;;1288:11:::1;1275:25:::0;;::::1;;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;;::::1;::::0;;;::::1;::::0;;;;;::::1;::::0;;;::::1;;;;::::0;;;::::1;::::0;;;;;;::::1;;::::0;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;;;;;;;;;;;;::::0;::::1;:12;:25::i;2068:95::-:0;1917:19:26;:17;:19::i;:::-;2131:25:5::1;::::0;;;;::::1;::::0;;2144:11:::1;2131:25:::0;;::::1;;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;;::::1;::::0;;;::::1;::::0;;;;;::::1;::::0;;;::::1;;;;::::0;;;::::1;::::0;;;;;;::::1;;::::0;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;;;;;;;;;;;;::::0;::::1;:12;:25::i;2066:108:25:-:0;1085:13:23;:11;:13::i;:::-;2130:37:25::1;2149:5;2164:1;2130:18;:37::i;2771:725:27:-:0;2855:15;;2971:1;1806:66;2929:38;2928:49;;2929:43;2976:1;2928:49;:::i;:::-;2921:3;:56;;2913:75;;;;;;;25742:2:31;2913:75:27;;;25724:21:31;25781:1;25761:18;;;25754:29;25819:8;25799:18;;;25792:36;25845:18;;2913:75:27;25540:329:31;2913:75:27;3007:1;3001:3;:7;2998:261;;;3024:13;3040:5;3044:1;3040:3;:5;:::i;:::-;3024:21;;3063:9;3059:190;3078:5;3074:1;:9;3059:190;;;3167:8;3176:3;:1;3178;3176:3;:::i;:::-;3167:13;;;;;;;;:::i;:::-;;;;;;;3153:27;;:8;3162:1;3153:11;;;;;;;;:::i;:::-;;;;;;;:27;;;3145:55;;;;;;;26076:2:31;3145:55:27;;;26058:21:31;26115:2;26095:18;;;26088:30;26154:17;26134:18;;;26127:45;26189:18;;3145:55:27;25874:339:31;3145:55:27;3229:3;;3059:190;;;;3010:249;2998:261;1806:66;3269:42;3359:131;3378:3;3374:1;:7;3359:131;;;3406:9;:24;3417:8;3426:1;3417:11;;;;;;;;:::i;:::-;;;;;;;;;;;;3406:24;;;;;;;;;;;;-1:-1:-1;3406:24:27;;;;3398:51;;;;;;;26420:2:31;3398:51:27;;;26402:21:31;26459:2;26439:18;;;26432:30;26498:16;26478:18;;;26471:44;26532:18;;3398:51:27;26218:338:31;3398:51:27;3474:3;;3359:131;;2640:125;1225:22:25;734:10:2;1836:111:25;:::i;1225:22::-;:49;;;-1:-1:-1;1238:7:23;1264:6;;;;;;1251:23:25;;734:10:2;1251:23:25;;;1225:49;1219:76;;1284:11;;;;;;;;;;;;;;1219:76;2719:39:27::1;2739:6;2755:1;2719:19;:39::i;4007:589:4:-:0;4193:52;;;4157:24;4193:52;;;;;4231:14;4193:52;;;;;;;;;;;;;;;;;;;;4255:23;;4193:52;;;4255:23;4318:61;;4157:24;;-1:-1:-1;;4318:61:4;;4193:52;;4340:25;;4367:11;;4318:61;;:::i;:::-;;;;;;;;;;;;;4308:72;;;;;;4289:91;;4415:4;:11;4401:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4401:26:4;;4391:36;;4442:9;4438:152;4455:4;:11;4453:1;:13;4438:152;;;4496:52;4506:8;4516:4;4521:1;4516:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4527:4;4532:1;4527:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4538:4;4543:1;4538:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4496:52;;;;;;;;;;;;;;;;;27759:25:31;;;27832:4;27820:17;;;;27815:2;27800:18;;27793:45;27869:2;27854:18;;27847:34;27912:2;27897:18;;27890:34;27746:3;27731:19;;27532:398;4496:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4483:7;4491:1;4483:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;4574:3;;4438:152;;;;4183:413;;4007:589;;;;;:::o;1914:148:5:-;1917:19:26;:17;:19::i;:::-;2018:37:5::1;2035:5;2042:12;2018:16;:37::i;:::-;1914:148:::0;;:::o;4822:551:4:-;4980:52;;;4944:24;4980:52;;;;;5018:14;4980:52;;;;;;;;;;;;;;;;;;;;;5042:23;;4980:52;;;5042:23;5105:52;;4944:24;;-1:-1:-1;;5105:52:4;;4980;;5018:14;;5150:6;;5105:52;;:::i;:::-;;;;;;;;;;;;;5095:63;;;;;;5076:82;;5192:4;:11;5178:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5178:26:4;;5168:36;;5219:9;5215:152;5232:4;:11;5230:1;:13;5215:152;;;5273:52;5283:8;5293:4;5298:1;5293:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5304:4;5309:1;5304:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5315:4;5320:1;5315:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5273:52;;;;;;;;;;;;;;;;;27759:25:31;;;27832:4;27820:17;;;;27815:2;27800:18;;27793:45;27869:2;27854:18;;27847:34;27912:2;27897:18;;27890:34;27746:3;27731:19;;27532:398;5273:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5260:7;5268:1;5260:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;5351:3;;5215:152;;3192:589;3378:52;;;3342:24;3378:52;;;;;3416:14;3378:52;;;;;;;;;;;;;;;;;;;;3440:23;;3378:52;;;3440:23;3503:61;;3342:24;;-1:-1:-1;;3503:61:4;;3378:52;;;;3552:11;;3503:61;;:::i;:::-;;;;;;;;;;;;;3493:72;;;;;;3474:91;;3600:4;:11;3586:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3586:26:4;;3576:36;;3627:9;3623:152;3640:4;:11;3638:1;:13;3623:152;;;3681:52;3691:8;3701:4;3706:1;3701:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3712:4;3717:1;3712:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3723:4;3728:1;3723:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3681:52;;;;;;;;;;;;;;;;;27759:25:31;;;27832:4;27820:17;;;;27815:2;27800:18;;27793:45;27869:2;27854:18;;27847:34;27912:2;27897:18;;27890:34;27746:3;27731:19;;27532:398;3681:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3668:7;3676:1;3668:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;3759:3;;3623:152;;2065:198:23;1085:13;:11;:13::i;:::-;2153:22:::1;::::0;::::1;2145:73;;;::::0;::::1;::::0;;29337:2:31;2145:73:23::1;::::0;::::1;29319:21:31::0;29376:2;29356:18;;;29349:30;29415:34;29395:18;;;29388:62;29486:8;29466:18;;;29459:36;29512:19;;2145:73:23::1;29135:402:31::0;2145:73:23::1;2228:28;2247:8;2228:18;:28::i;2169:549:5:-:0;1917:19:26;:17;:19::i;:::-;2235:30:5::1;2268:20;:18;:20::i;:::-;2321:11;::::0;2235:53;;-1:-1:-1;2321:11:5::1;;2351:10;:26:::0;::::1;2343:43;;;;;;;;;;;29744:2:31::0;29726:21;;;29783:1;29763:18;;;29756:29;29821:6;29816:2;29801:18;;29794:34;29860:2;29845:18;;29542:327;2343:43:5::1;2397:17;2404:9;2397:6;:17::i;:::-;2474:9;2425:8;:19;;;:37;;:59;;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;2494:19:5::1;::::0;::::1;::::0;:42:::1;;:64:::0;;2548:9:::1;::::0;2494:42;:64:::1;::::0;2548:9;;2494:64:::1;:::i;:::-;;;::::0;;-1:-1:-1;2586:19:5::1;::::0;::::1;::::0;2569:37:::1;::::0;6000:23:4;;;;;;;;;;;;;;;;:10;:23;5926:104;2569:37:5::1;2617:18;2638:16;:14;:16::i;:::-;2617:37;;2687:12;2669:42;;2674:11;2669:42;;;2701:9;2669:42;;;;1766:25:31::0;;1754:2;1739:18;;1620:177;2669:42:5::1;;;;;;;;2225:493;;;2169:549::o:0;1350:130:23:-;1238:7;1264:6;1413:23;1264:6;;;;;734:10:2;1413:23:23;1405:68;;;;;;;30278:2:31;1405:68:23;;;30260:21:31;;;30297:18;;;30290:30;30356:34;30336:18;;;30329:62;30408:18;;1405:68:23;30076:356:31;3006:224:25;3091:33;3107:9;3118:5;3091:15;:33::i;:::-;3134:32;3150:9;3161:4;3134:15;:32::i;:::-;3213:9;3181:42;;3202:9;3181:42;;;;;;;;;;;;3006:224;;:::o;3109:119:26:-;2164:16;:14;:16::i;:::-;814:66;1060:54;;;;;;3199:22:::1;734:10:2::0;3208:12:26::1;3199:22;::::0;1188:42:31;1176:55;;;1158:74;;1146:2;1131:18;3199:22:26::1;;;;;;;3109:119::o:0;1362:233:25:-;1444:16;1264:6:23;;;;;;1484:18:25;1264:6:23;1484:8:25;:18::i;:::-;1480:64;;;1504:40;1523:8;1541:1;1504:18;:40::i;:::-;1554:34;1579:8;1554:24;:34::i;4192:227:27:-;4280:33;4295:10;4307:5;4280:14;:33::i;:::-;4323:32;4338:10;4350:4;4323:14;:32::i;:::-;4401:10;4370:42;;4389:10;4370:42;;;;;;;;;;;;4192:227;;:::o;5562:232:4:-;5615:30;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5615:30:4;5657:48;;;;;;;;5687:18;5657:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:27;;;:48;;;;5715:30;;;;;;;5736:9;5715:30;;;;;;;;;;;;;;;;;;;;5755:32;;;;;;;5777:10;5755:32;;;;;;;;;;;;;;;;;:19;;;:32;5657:8;5562:232::o;4111:468:5:-;-1:-1:-1;;;;;;;;;;;;;;;;;4331:49:5;4354:8;4364:9;4375:4;4331:22;:49::i;:::-;4440:16;;;;4391:19;;;;:66;;;;4440:16;;4391:66;:::i;:::-;;;;;-1:-1:-1;4500:17:5;;4519:16;;;;;4473:63;;1766:25:31;;;4473:63:5;;;;;;;;;;;1739:18:31;4473:63:5;;;;;;;-1:-1:-1;4553:19:5;;;;4111:468;;;;;;;:::o;4585:1097::-;4708:45;;;;;;;;4742:11;4708:45;;;;;;;;;;;;;;;;;;;;;;;;;4666:30;;4708:31;;:45;4742:11;4708:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4763:19;4797:12;:27;;;4763:62;;4836:21;4859:20;4883:61;4904:12;4926:9;:16;;;4883:20;:61::i;:::-;4835:109;;;;4955:17;4987:9;4983:612;5000:6;:13;4998:1;:15;4983:612;;;5046:3;5050:1;5046:6;;;;;;;;:::i;:::-;;;;;;;5034:18;;;;5083:7;:23;;;5124:6;5131:1;5124:9;;;;;;;;:::i;:::-;;;;;;;5168:6;5175:1;5168:9;;;;;;;;:::i;:::-;;;;;;;;;;;5083:278;;;;;;;;;;30959:4:31;30947:17;;;5083:278:5;;;30929:36:31;31001:17;;30981:18;;;30974:45;31035:18;;;31028:34;;;5265:4:5;31078:18:31;;;31071:83;5295:5:5;31170:19:31;;;31163:51;;;31230:19;;;31223:51;30901:19;;5083:278:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5066:3;5070:1;5066:6;;;;;;;;:::i;:::-;;;;;;:296;;;;;;;;;;;5423:1;5385:40;;:18;:26;5404:3;5408:1;5404:6;;;;;;;;:::i;:::-;;;;;;;;;;;;5385:26;;;;;;;;;;;;-1:-1:-1;5385:26:5;;;;:40;5377:65;;;;;;;31676:2:31;5377:65:5;;;31658:21:31;31715:2;31695:18;;;31688:30;31754:14;31734:18;;;31727:42;31786:18;;5377:65:5;31474:336:31;5377:65:5;5485:9;:17;;;5456:18;:26;5475:3;5479:1;5475:6;;;;;;;;:::i;:::-;;;;;;;5456:26;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;5555:6;5562:1;5555:9;;;;;;;;:::i;:::-;;;;;;;5521:63;;5536:9;:17;;;5521:63;;;5566:3;5570:1;5566:6;;;;;;;;:::i;:::-;;;;;;;5574:9;5521:63;;;;;;32019:34:31;32007:47;;;;31989:66;;32086:2;32071:18;;32064:34;31977:2;31962:18;;31815:289;5521:63:5;;;;;;;;5015:3;;4983:612;;;-1:-1:-1;5671:3:5;;4585:1097;-1:-1:-1;;;;;;4585:1097:5:o;7173:553::-;7302:11;;7246:21;;7302:11;;;7323:48;;;;;;;32311:2:31;7323:48:5;;;32293:21:31;32350:1;32330:18;;;32323:29;32388:11;32368:18;;;32361:39;32417:18;;7323:48:5;32109:332:31;7323:48:5;7416:27;;7471:20;;;;;-1:-1:-1;7382:19:5;7502:126;7519:12;:19;;;:26;7517:1;:28;7502:126;;;7566:7;:13;;;7580:12;:19;;;7600:1;7580:22;;;;;;;;:::i;:::-;;;;;;;7604:12;7566:51;;;;;;;;;;;;;;;32648:4:31;32636:17;;;;32618:36;;32702:42;32690:55;32685:2;32670:18;;32663:83;32606:2;32591:18;;32446:306;7566:51:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7547:3:5;;;;;-1:-1:-1;7502:126:5;;-1:-1:-1;7502:126:5;;-1:-1:-1;7683:36:5;7706:13;7683:20;;;;:36;:::i;6518:441:4:-;6698:22;6722:17;6751:55;6778:6;6786:19;6751:26;:55::i;:::-;6828:28;6837:6;6845:10;6828:8;:28::i;:::-;6816:40;;6883:9;6874:6;:18;6866:41;;;;;;;32959:2:31;6866:41:4;;;32941:21:31;32998:2;32978:18;;;32971:30;33037:12;33017:18;;;33010:40;33067:18;;6866:41:4;32757:334:31;6866:41:4;6934:18;6943:9;6934:6;:18;:::i;:::-;6917:35;;6518:441;;;;;;:::o;6965:316::-;7112:15;;;;7165:14;;294:5;7103:35;:24;;;;;:35;;;;;7153:26;;7150:57;;;-1:-1:-1;7193:14:4;;7150:57;7232:10;:14;;;7220:9;:26;7217:57;;;-1:-1:-1;7260:14:4;;;;6965:316;-1:-1:-1;6965:316:4:o;2860:117:26:-;1917:19;:17;:19::i;:::-;814:66;1060:54;;;;2930:4:::1;1060:54:::0;;;2950:20:::1;734:10:2::0;2957:12:26::1;655:96:2::0;2431:272:25;2660:34;;;33489:42:31;33477:55;;2660:34:25;;;33459:74:31;1111:66:25;33549:18:31;;;33542:34;;;;2493:31:25;;2623:73;;33432:18:31;;2660:34:25;;;;;;;;;;;;2650:45;;;;;;1005:4:27;847:170;6674:198:0;6757:12;6788:77;6809:6;6817:4;6788:77;;;;;;;;;;;;;;;;;:20;:77::i;:::-;6781:84;6674:198;-1:-1:-1;;;6674:198:0:o;3512:593:5:-;3563:45;;;;;;;;3597:11;3563:45;;;;;;;;;;;;;;;;;;;;;;;;;:31;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;3563:45:5;;;;-1:-1:-1;;3652:27:5;;3563:45;;-1:-1:-1;3618:19:5;;-1:-1:-1;3618:19:5;3738:49;3563:45;3779:6;3738:18;:49::i;:::-;3690:97;;;;3801:9;3797:302;3814:6;:13;3812:1;:15;3797:302;;;3848:7;:15;;;3871:3;3875:1;3871:6;;;;;;;;:::i;:::-;;;;;;;3848:240;;3896:6;3903:1;3896:9;;;;;;;;:::i;:::-;;;;;;;3939:3;3943:1;3939:6;;;;;;;;:::i;:::-;;;;;;;;;;;3848:240;;;;;;;;;;33878:4:31;33866:17;;;3848:240:5;;;33848:36:31;33932:34;33920:47;33900:18;;;33893:75;3988:4:5;33984:18:31;;;33977:83;4025:5:5;34076:18:31;;;34069:50;;;34135:19;;;34128:51;33820:19;;3848:240:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3829:3:5;;;;;-1:-1:-1;3797:302:5;;-1:-1:-1;;3797:302:5;;;3553:552;;;;3512:593;:::o;2724:782::-;-1:-1:-1;;;;;;;;;;;;;;;;;2924:17:5;2952:73;2979:9;:16;;;2997:8;:27;;;2952:26;:73::i;:::-;3039:11;3035:221;;;3078:46;3087:9;:16;;;3105:8;:18;;;3078:8;:46::i;:::-;3066:58;;3165:9;3146;:16;;;:28;3138:51;;;;;;;32959:2:31;3138:51:5;;;32941:21:31;32998:2;32978:18;;;32971:30;33037:12;33017:18;;;33010:40;33067:18;;3138:51:5;32757:334:31;3138:51:5;3214:16;;;:29;;;;;;;3035:221;3314:16;;;;3265:19;;;;:66;;;;3314:16;;3265:66;:::i;:::-;;;;;-1:-1:-1;3342:18:5;3363:16;:14;:16::i;:::-;3342:37;;3416:9;:17;;;3394:69;;3403:11;3394:69;;;3435:9;:16;;;3453:9;3394:69;;;;;;12347:25:31;;;12403:2;12388:18;;12381:34;12335:2;12320:18;;12173:248;3394:69:5;;;;;;;;-1:-1:-1;;;3480:19:5;;;;2724:782;;;;;:::o;5688:838::-;5770:15;5788:32;;;:18;:32;;;;;;;;;5830:53;;;;;;;34392:2:31;5830:53:5;;;34374:21:31;34431:2;34411:18;;;34404:30;34470:21;34450:18;;;34443:49;34509:18;;5830:53:5;34190:343:31;5830:53:5;5900:32;;;;:18;:32;;;;;;;;5893:39;;;;;;5977:11;:26;;6031:23;;;;;;;5893:39;5977:26;;;;5900:32;5977:26;;6031:21;;:23;;;;;;;;;;5900:32;5977:26;6031:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;;;6080:12;6031:62;;;;;;;;;;;;;1766:25:31;;1754:2;1739:18;;1620:177;6031:62:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:69;;;6165:151;;;;;;;;35925:25:31;;;35966:18;;;35959:34;;;6165:16:5;36029:55:31;;;36009:18;;;36002:83;6031:69:5;;-1:-1:-1;6134:21:5;;6165:16;;;;;35898:18:31;;6165:151:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6375:6;6358:13;6334:21;:37;;;;:::i;:::-;:47;6326:75;;;;;;;36298:2:31;6326:75:5;;;36280:21:31;36337:2;36317:18;;;36310:30;36376:17;36356:18;;;36349:45;36411:18;;6326:75:5;36096:339:31;6326:75:5;6411:48;6442:7;6452:6;6411:22;:48::i;:::-;;6506:12;6499:5;6490:7;6474:45;;;;;;;;;;;;5760:766;;;;5688:838;;:::o;772:88:4:-;841:10;:12;;816:6;;841:12;;;;;816:6;841:12;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;834:19;;772:88;:::o;2709:291:25:-;2783:19;;;;2779:215;;2818:42;2863:21;2878:5;2863:14;:21::i;:::-;2902:16;;2818:66;;-1:-1:-1;2902:24:25;;;:16;;;;:24;;;2898:48;;2935:11;;;;;;;;;;;;;;2898:48;2960:23;;;;;;;;;;;;2709:291;;:::o;2623:102:26:-;2686:8;:6;:8::i;:::-;2681:37;;2703:15;;;;;;;;;;;;;;2417:187:23;2490:16;2509:6;;;2525:17;;;2509:6;2525:17;;;;;;;;;2557:40;;2509:6;;;;;;;2525:17;;2509:6;;2557:40;;;2480:124;2417:187;:::o;3782:404:27:-;3856:20;;;;3852:328;;3896:43;;;;;;;1806:66;3896:43;;;;;;:51;;;:43;;;;:51;;;3892:76;;3956:12;;;;;;;;;;;;;;3892:76;3982:43;;;;;;;1806:66;3982:43;;;;;:50;;;;;;;;;;;;;;;4047:122;;1806:66;4056:46;;;;;;;-1:-1:-1;4056:46:27;;;;;;;;;;;;;;;;;;;;1914:148:5;;:::o;4047:122:27:-;4121:48;1806:66;4161:6;4121:38;:48::i;4602:214:4:-;4745:64;4758:49;4782:5;4789:11;4802:4;4758:23;:49::i;6908:259:5:-;7041:21;7072:24;7120:40;7139:12;7153:6;7120:18;:40::i;:::-;7113:47;;;;6908:259;;;;;;:::o;7287:246:4:-;7418:23;;:33;-1:-1:-1;7418:33:4;7410:53;;;;;;;36856:2:31;7410:53:4;;;36838:21:31;36895:1;36875:18;;;36868:29;36933:9;36913:18;;;36906:37;36960:18;;7410:53:4;36654:330:31;7410:53:4;7508:6;7481:19;:23;;;:33;;7473:53;;;;;;;37191:2:31;7473:53:4;;;37173:21:31;37230:1;37210:18;;;37203:29;37268:9;37248:18;;;37241:37;37295:18;;7473:53:4;36989:330:31;7058:325:0;7199:12;7224;7238:23;7265:6;:19;;7285:4;7265:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7223:67;;;;7307:69;7334:6;7342:7;7351:10;7363:12;7307:26;:69::i;:::-;7300:76;7058:325;-1:-1:-1;;;;;;7058:325:0:o;6532:370:5:-;6663:21;6694:24;6743:12;:19;;;:26;6773:1;6743:31;6735:57;;;;;;;37818:2:31;6735:57:5;;;37800:21:31;37857:2;37837:18;;;37830:30;37896:15;37876:18;;;37869:43;37929:18;;6735:57:5;37616:337:31;6735:57:5;6811:19;;;;6850:16;;;6864:1;6850:16;;;;;;;;;6811:19;;-1:-1:-1;6850:16:5;;;;;;;;;;;;-1:-1:-1;6850:16:5;6840:26;;6889:6;6876:7;6884:1;6876:10;;;;;;;;:::i;:::-;;;;;;:19;;;;;;;;;;;6532:370;;;;;:::o;6036:476:4:-;6143:12;6200:6;6175:21;:31;;6167:59;;;;;;;38160:2:31;6167:59:4;;;38142:21:31;38199:2;38179:18;;;38172:30;38238:17;38218:18;;;38211:45;38273:18;;6167:59:4;37958:339:31;6167:59:4;6251:38;;:14;;;;6274:6;;6251:38;;;;6274:6;6251:14;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6237:52;;;;;6304:7;6299:207;;6346:9;6332:32;;;6357:6;6332:32;;;;1766:25:31;;1754:2;1739:18;;1620:177;6332:32:4;;;;;;;;6379:13;1264:6:23;;;;;;;6398:21:4;;6428:6;6398:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6378:65;;;6465:8;6457:38;;;;;;;38714:2:31;6457:38:4;;;38696:21:31;38753:2;38733:18;;;38726:30;38792:19;38772:18;;;38765:47;38829:18;;6457:38:4;38512:341:31;6457:38:4;6313:193;6036:476;;;;:::o;1243:311:27:-;1329:10;;1315:11;1349:199;1366:3;1364:1;:5;1349:199;;;1397:3;1401:1;1397:6;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;1389:14;;;;1386:122;;1432:3;1436:5;1440:1;1436:3;:5;:::i;:::-;1432:10;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;1423:3;1427:1;1423:6;;;;;;;;:::i;:::-;;;;;;;;;:19;;;;;;;;;;;;;;;;;;1460:3;:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1243:311:27:o;1386:122::-;1532:3;;1349:199;;7671:628:0;7851:12;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;1713:19:1;;;;8113:60:0;;;;;;;39249:2:31;8113:60:0;;;39231:21:31;39288:2;39268:18;;;39261:30;39327:31;39307:18;;;39300:59;39376:18;;8113:60:0;39047:353:31;8113:60:0;-1:-1:-1;8208:10:0;8201:17;;7875:418;8249:33;8257:10;8269:12;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;;;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;211:154:31;297:42;290:5;286:54;279:5;276:65;266:93;;355:1;352;345:12;370:247;429:6;482:2;470:9;461:7;457:23;453:32;450:52;;;498:1;495;488:12;450:52;537:9;524:23;556:31;581:5;556:31;:::i;827:180::-;886:6;939:2;927:9;918:7;914:23;910:32;907:52;;;955:1;952;945:12;907:52;-1:-1:-1;978:23:31;;827:180;-1:-1:-1;827:180:31:o;1802:184::-;1854:77;1851:1;1844:88;1951:4;1948:1;1941:15;1975:4;1972:1;1965:15;1991:251;2063:2;2057:9;2105:2;2093:15;;2138:18;2123:34;;2159:22;;;2120:62;2117:88;;;2185:18;;:::i;:::-;2221:2;2214:22;1991:251;:::o;2247:257::-;2319:4;2313:11;;;2351:17;;2398:18;2383:34;;2419:22;;;2380:62;2377:88;;;2445:18;;:::i;2509:334::-;2580:2;2574:9;2636:2;2626:13;;2641:66;2622:86;2610:99;;2739:18;2724:34;;2760:22;;;2721:62;2718:88;;;2786:18;;:::i;:::-;2822:2;2815:22;2509:334;;-1:-1:-1;2509:334:31:o;2848:163::-;2915:20;;2975:10;2964:22;;2954:33;;2944:61;;3001:1;2998;2991:12;2944:61;2848:163;;;:::o;3016:415::-;3102:6;3155:2;3143:9;3134:7;3130:23;3126:32;3123:52;;;3171:1;3168;3161:12;3123:52;3197:22;;:::i;:::-;3255:9;3242:23;3235:5;3228:38;3326:2;3315:9;3311:18;3298:32;3293:2;3286:5;3282:14;3275:56;3363:37;3396:2;3385:9;3381:18;3363:37;:::i;:::-;3358:2;3347:14;;3340:61;3351:5;3016:415;-1:-1:-1;;;3016:415:31:o;3747:279::-;3524:12;;3538:10;3520:29;3508:42;;3603:4;3592:16;;;3586:23;3611:42;3582:72;3566:14;;;3559:96;3708:4;3697:16;;;3691:23;3716:18;3687:48;3671:14;;;3664:72;3953:2;3938:18;;3965:55;3436:306;4223:181;4281:4;4314:18;4306:6;4303:30;4300:56;;;4336:18;;:::i;:::-;-1:-1:-1;4381:1:31;4377:14;4393:4;4373:25;;4223:181::o;4409:156::-;4475:20;;4535:4;4524:16;;4514:27;;4504:55;;4555:1;4552;4545:12;4570:1039;4628:5;4676:4;4664:9;4659:3;4655:19;4651:30;4648:50;;;4694:1;4691;4684:12;4648:50;4716:22;;:::i;:::-;4707:31;;4775:9;4762:23;4794:33;4819:7;4794:33;:::i;:::-;4836:22;;4877:2;4915:18;;;4902:32;4957:18;4946:30;;4943:50;;;4989:1;4986;4979:12;4943:50;5012:22;;5065:4;5057:13;;5053:23;-1:-1:-1;5043:51:31;;5090:1;5087;5080:12;5043:51;5126:2;5113:16;5149:58;5165:41;5203:2;5165:41;:::i;:::-;5149:58;:::i;:::-;5241:15;;;5323:1;5319:10;;;;5311:19;;5307:28;;;5272:12;;;;5347:15;;;5344:35;;;5375:1;5372;5365:12;5344:35;5399:11;;;;5419:146;5435:6;5430:3;5427:15;5419:146;;;5501:21;5518:3;5501:21;:::i;:::-;5489:34;;5452:12;;;;5543;;;;5419:146;;;5597:5;5592:2;5585:5;5581:14;5574:29;;;;;;4570:1039;;;;:::o;5614:488::-;5711:6;5719;5772:2;5760:9;5751:7;5747:23;5743:32;5740:52;;;5788:1;5785;5778:12;5740:52;5827:9;5814:23;5846:31;5871:5;5846:31;:::i;:::-;5896:5;-1:-1:-1;5952:2:31;5937:18;;5924:32;5979:18;5968:30;;5965:50;;;6011:1;6008;6001:12;5965:50;6034:62;6088:7;6079:6;6068:9;6064:22;6034:62;:::i;:::-;6024:72;;;5614:488;;;;;:::o;6493:353::-;6581:6;6634:2;6622:9;6613:7;6609:23;6605:32;6602:52;;;6650:1;6647;6640:12;6602:52;6690:9;6677:23;6723:18;6715:6;6712:30;6709:50;;;6755:1;6752;6745:12;6709:50;6778:62;6832:7;6823:6;6812:9;6808:22;6778:62;:::i;6851:188::-;6919:20;;6979:34;6968:46;;6958:57;;6948:85;;7029:1;7026;7019:12;7044:661;7139:6;7192:3;7180:9;7171:7;7167:23;7163:33;7160:53;;;7209:1;7206;7199:12;7160:53;7242:2;7236:9;7284:3;7276:6;7272:16;7354:6;7342:10;7339:22;7318:18;7306:10;7303:34;7300:62;7297:88;;;7365:18;;:::i;:::-;7405:10;7401:2;7394:22;;7453:9;7440:23;7432:6;7425:39;7525:2;7514:9;7510:18;7497:32;7492:2;7484:6;7480:15;7473:57;7563:38;7597:2;7586:9;7582:18;7563:38;:::i;:::-;7558:2;7550:6;7546:15;7539:63;7635:38;7669:2;7658:9;7654:18;7635:38;:::i;:::-;7630:2;7618:15;;7611:63;7622:6;7044:661;-1:-1:-1;;;7044:661:31:o;7710:794::-;7798:6;7806;7814;7822;7875:2;7863:9;7854:7;7850:23;7846:32;7843:52;;;7891:1;7888;7881:12;7843:52;7930:9;7917:23;7949:31;7974:5;7949:31;:::i;:::-;7999:5;-1:-1:-1;8051:2:31;8036:18;;8023:32;;-1:-1:-1;8106:2:31;8091:18;;8078:32;8129:18;8159:14;;;8156:34;;;8186:1;8183;8176:12;8156:34;8224:6;8213:9;8209:22;8199:32;;8269:7;8262:4;8258:2;8254:13;8250:27;8240:55;;8291:1;8288;8281:12;8240:55;8331:2;8318:16;8357:2;8349:6;8346:14;8343:34;;;8373:1;8370;8363:12;8343:34;8418:7;8413:2;8404:6;8400:2;8396:15;8392:24;8389:37;8386:57;;;8439:1;8436;8429:12;8386:57;7710:794;;;;-1:-1:-1;;8470:2:31;8462:11;;-1:-1:-1;;;7710:794:31:o;8509:250::-;8594:1;8604:113;8618:6;8615:1;8612:13;8604:113;;;8694:11;;;8688:18;8675:11;;;8668:39;8640:2;8633:10;8604:113;;;-1:-1:-1;;8751:1:31;8733:16;;8726:27;8509:250::o;8764:329::-;8805:3;8843:5;8837:12;8870:6;8865:3;8858:19;8886:76;8955:6;8948:4;8943:3;8939:14;8932:4;8925:5;8921:16;8886:76;:::i;:::-;9007:2;8995:15;9012:66;8991:88;8982:98;;;;9082:4;8978:109;;8764:329;-1:-1:-1;;8764:329:31:o;9098:298::-;9281:6;9274:14;9267:22;9256:9;9249:41;9326:2;9321;9310:9;9306:18;9299:30;9230:4;9346:44;9386:2;9375:9;9371:18;9363:6;9346:44;:::i;9401:171::-;9468:20;;9528:18;9517:30;;9507:41;;9497:69;;9562:1;9559;9552:12;9577:1050;9634:5;9687:3;9680:4;9672:6;9668:17;9664:27;9654:55;;9705:1;9702;9695:12;9654:55;9741:6;9728:20;9767:4;9791:58;9807:41;9845:2;9807:41;:::i;9791:58::-;9883:15;;;9945:4;9988:13;;;9976:26;;9972:35;;;9914:12;;;;9871:3;10019:15;;;10016:35;;;10047:1;10044;10037:12;10016:35;10083:2;10075:6;10071:15;10095:503;10111:6;10106:3;10103:15;10095:503;;;10187:2;10181:3;10176;10172:13;10168:22;10165:112;;;10231:1;10260:2;10256;10249:14;10165:112;10303:22;;:::i;:::-;10352:21;10369:3;10352:21;:::i;:::-;10338:36;;10423:12;;;10410:26;10394:14;;;10387:50;10460:2;10511:12;;;10498:26;10482:14;;;10475:50;10538:18;;10576:12;;;;10128;;10095:503;;;-1:-1:-1;10616:5:31;;9577:1050;-1:-1:-1;;;;;;;9577:1050:31:o;10632:899::-;10791:6;10799;10807;10851:9;10842:7;10838:23;10881:3;10877:2;10873:12;10870:32;;;10898:1;10895;10888:12;10870:32;10921:28;10939:9;10921:28;:::i;:::-;10911:38;;11042:4;10973:66;10969:2;10965:75;10961:86;10958:106;;;11060:1;11057;11050:12;10958:106;;11086:22;;:::i;:::-;11160:2;11149:9;11145:18;11132:32;11173:33;11198:7;11173:33;:::i;:::-;11215:22;;11297:4;11282:20;;11269:34;11264:2;11253:14;;11246:58;11222:5;-1:-1:-1;11379:2:31;11364:18;;11351:32;11406:18;11395:30;;11392:50;;;11438:1;11435;11428:12;11392:50;11461:64;11517:7;11508:6;11497:9;11493:22;11461:64;:::i;:::-;11451:74;;;10632:899;;;;;:::o;11536:632::-;11707:2;11759:21;;;11829:13;;11732:18;;;11851:22;;;11678:4;;11707:2;11930:15;;;;11904:2;11889:18;;;11678:4;11973:169;11987:6;11984:1;11981:13;11973:169;;;12048:13;;12036:26;;12117:15;;;;12082:12;;;;12009:1;12002:9;11973:169;;12989:681;13160:2;13212:21;;;13282:13;;13185:18;;;13304:22;;;13131:4;;13160:2;13383:15;;;;13357:2;13342:18;;;13131:4;13426:218;13440:6;13437:1;13434:13;13426:218;;;13505:13;;13520:42;13501:62;13489:75;;13619:15;;;;13584:12;;;;13462:1;13455:9;13426:218;;13675:626;13772:6;13780;13833:2;13821:9;13812:7;13808:23;13804:32;13801:52;;;13849:1;13846;13839:12;13801:52;13889:9;13876:23;13918:18;13959:2;13951:6;13948:14;13945:34;;;13975:1;13972;13965:12;13945:34;14013:6;14002:9;13998:22;13988:32;;14058:7;14051:4;14047:2;14043:13;14039:27;14029:55;;14080:1;14077;14070:12;14029:55;14120:2;14107:16;14146:2;14138:6;14135:14;14132:34;;;14162:1;14159;14152:12;14132:34;14215:7;14210:2;14200:6;14197:1;14193:14;14189:2;14185:23;14181:32;14178:45;14175:65;;;14236:1;14233;14226:12;14175:65;14267:2;14259:11;;;;;14289:6;;-1:-1:-1;13675:626:31;;-1:-1:-1;;;;13675:626:31:o;14306:859::-;14466:4;14495:2;14535;14524:9;14520:18;14565:2;14554:9;14547:21;14588:6;14623;14617:13;14654:6;14646;14639:22;14692:2;14681:9;14677:18;14670:25;;14754:2;14744:6;14741:1;14737:14;14726:9;14722:30;14718:39;14704:53;;14792:2;14784:6;14780:15;14813:1;14823:313;14837:6;14834:1;14831:13;14823:313;;;14926:66;14914:9;14906:6;14902:22;14898:95;14893:3;14886:108;15017:39;15049:6;15040;15034:13;15017:39;:::i;:::-;15007:49;-1:-1:-1;15114:12:31;;;;15079:15;;;;14859:1;14852:9;14823:313;;;-1:-1:-1;15153:6:31;;14306:859;-1:-1:-1;;;;;;;14306:859:31:o;15170:502::-;15265:6;15318:2;15306:9;15297:7;15293:23;15289:32;15286:52;;;15334:1;15331;15324:12;15286:52;15360:22;;:::i;:::-;15405:28;15423:9;15405:28;:::i;:::-;15398:5;15391:43;15486:2;15475:9;15471:18;15458:32;15499:33;15524:7;15499:33;:::i;:::-;15559:2;15548:14;;15541:31;15604:37;15637:2;15622:18;;15604:37;:::i;15677:857::-;15856:2;15867:21;;;15969:13;;15984:42;15965:62;15945:18;;;15938:90;16063:15;;;16057:22;16117:4;16095:20;;;16088:34;16171:19;;15926:2;15911:18;;16199:22;;;15827:4;;15856:2;16279:21;;;15827:4;;16252:3;16237:19;;;16328:180;16342:6;16339:1;16336:13;16328:180;;;16407:13;;16422:4;16403:24;16391:37;;16483:15;;;;16364:1;16357:9;;;;;16448:12;;;;16328:180;;;-1:-1:-1;16525:3:31;15677:857;-1:-1:-1;;;;;;15677:857:31:o;16539:964::-;16623:6;16654:2;16697;16685:9;16676:7;16672:23;16668:32;16665:52;;;16713:1;16710;16703:12;16665:52;16753:9;16740:23;16786:18;16778:6;16775:30;16772:50;;;16818:1;16815;16808:12;16772:50;16841:22;;16894:4;16886:13;;16882:27;-1:-1:-1;16872:55:31;;16923:1;16920;16913:12;16872:55;16959:2;16946:16;16982:58;16998:41;17036:2;16998:41;:::i;16982:58::-;17074:15;;;17156:1;17152:10;;;;17144:19;;17140:28;;;17105:12;;;;17180:19;;;17177:39;;;17212:1;17209;17202:12;17177:39;17236:11;;;;17256:217;17272:6;17267:3;17264:15;17256:217;;;17352:3;17339:17;17369:31;17394:5;17369:31;:::i;:::-;17413:18;;17289:12;;;;17451;;;;17256:217;;;17492:5;16539:964;-1:-1:-1;;;;;;;16539:964:31:o;17508:248::-;17576:6;17584;17637:2;17625:9;17616:7;17612:23;17608:32;17605:52;;;17653:1;17650;17643:12;17605:52;-1:-1:-1;;17676:23:31;;;17746:2;17731:18;;;17718:32;;-1:-1:-1;17508:248:31:o;17761:512::-;17883:6;17891;17899;17952:2;17940:9;17931:7;17927:23;17923:32;17920:52;;;17968:1;17965;17958:12;17920:52;17991:28;18009:9;17991:28;:::i;:::-;17981:38;;18066:2;18055:9;18051:18;18038:32;18028:42;;18121:2;18110:9;18106:18;18093:32;18148:18;18140:6;18137:30;18134:50;;;18180:1;18177;18170:12;18278:965;18437:6;18445;18453;18497:9;18488:7;18484:23;18527:3;18523:2;18519:12;18516:32;;;18544:1;18541;18534:12;18516:32;18567:28;18585:9;18567:28;:::i;:::-;18557:38;;18688:4;18619:66;18615:2;18611:75;18607:86;18604:106;;;18706:1;18703;18696:12;18604:106;;18732:22;;:::i;:::-;18806:2;18795:9;18791:18;18778:32;18819:33;18844:7;18819:33;:::i;:::-;18861:22;;18943:2;18928:18;;;18915:32;18910:2;18899:14;;18892:56;19008:4;18993:20;;18980:34;18964:14;;;18957:58;18868:5;-1:-1:-1;19090:3:31;19075:19;;19062:33;19118:18;19107:30;;19104:50;;;19150:1;19147;19140:12;19248:184;19300:77;19297:1;19290:88;19397:4;19394:1;19387:15;19421:4;19418:1;19411:15;22081:271;22264:6;22256;22251:3;22238:33;22220:3;22290:16;;22315:13;;;22290:16;22081:271;-1:-1:-1;22081:271:31:o;22694:184::-;22746:77;22743:1;22736:88;22843:4;22840:1;22833:15;22867:4;22864:1;22857:15;22883:128;22950:9;;;22971:11;;;22968:37;;;22985:18;;:::i;23352:580::-;23429:4;23435:6;23495:11;23482:25;23585:66;23574:8;23558:14;23554:29;23550:102;23530:18;23526:127;23516:155;;23667:1;23664;23657:12;23516:155;23694:33;;23746:20;;;-1:-1:-1;23789:18:31;23778:30;;23775:50;;;23821:1;23818;23811:12;23775:50;23854:4;23842:17;;-1:-1:-1;23885:14:31;23881:27;;;23871:38;;23868:58;;;23922:1;23919;23912:12;23937:440;24166:6;24158;24153:3;24140:33;24122:3;24201:6;24196:3;24192:16;24228:1;24224:2;24217:13;24259:6;24253:13;24275:65;24333:6;24329:2;24322:4;24314:6;24310:17;24275:65;:::i;:::-;24356:15;;23937:440;-1:-1:-1;;;;;23937:440:31:o;25410:125::-;25475:9;;;25496:10;;;25493:36;;;25509:18;;:::i;26561:301::-;26649:1;26642:5;26639:12;26629:200;;26685:77;26682:1;26675:88;26786:4;26783:1;26776:15;26814:4;26811:1;26804:15;26629:200;26838:18;;26561:301::o;26867:660::-;3524:12;;3538:10;3520:29;3508:42;;3603:4;3592:16;;;3586:23;3611:42;3582:72;3566:14;;;3559:96;3708:4;3697:16;;;3691:23;3716:18;3687:48;3671:14;;;3664:72;27222:3;27207:19;;27299:60;27355:2;27344:9;27340:18;27332:6;27299:60;:::i;:::-;27415:42;27406:6;27400:13;27396:62;27390:3;27379:9;27375:19;27368:91;27514:4;27506:6;27502:17;27496:24;27490:3;27479:9;27475:19;27468:53;26867:660;;;;;;:::o;27935:468::-;3524:12;;3538:10;3520:29;3508:42;;3603:4;3592:16;;;3586:23;3611:42;3582:72;3566:14;;;3559:96;3708:4;3697:16;;;3691:23;3716:18;3687:48;3671:14;;;3664:72;28216:3;28201:19;;28293:60;28349:2;28338:9;28334:18;28326:6;28293:60;:::i;:::-;28390:6;28384:3;28373:9;28369:19;28362:35;27935:468;;;;;;:::o;28408:722::-;3524:12;;3538:10;3520:29;3508:42;;3603:4;3592:16;;;3586:23;3611:42;3582:72;3566:14;;;3559:96;3708:4;3697:16;;;3691:23;3716:18;3687:48;3671:14;;;3664:72;28763:3;28748:19;;28840:60;28896:2;28885:9;28881:18;28873:6;28840:60;:::i;:::-;28956:42;28947:6;28941:13;28937:62;28931:3;28920:9;28916:19;28909:91;29055:4;29047:6;29043:17;29037:24;29031:3;29020:9;29016:19;29009:53;29117:4;29109:6;29105:17;29099:24;29093:3;29082:9;29078:19;29071:53;28408:722;;;;;;:::o;29874:197::-;29942:34;29996:10;;;30008;;;29992:27;;30031:11;;;30028:37;;;30045:18;;:::i;30437:200::-;30506:34;30573:10;;;30561;;;30557:27;;30596:12;;;30593:38;;;30611:18;;:::i;31285:184::-;31355:6;31408:2;31396:9;31387:7;31383:23;31379:32;31376:52;;;31424:1;31421;31414:12;31376:52;-1:-1:-1;31447:16:31;;31285:184;-1:-1:-1;31285:184:31:o;34538:274::-;34631:6;34684:2;34672:9;34663:7;34659:23;34655:32;34652:52;;;34700:1;34697;34690:12;34652:52;34732:9;34726:16;34751:31;34776:5;34751:31;:::i;34817:885::-;34926:6;34979:3;34967:9;34958:7;34954:23;34950:33;34947:53;;;34996:1;34993;34986:12;34947:53;35029:2;35023:9;35071:3;35063:6;35059:16;35141:6;35129:10;35126:22;35105:18;35093:10;35090:34;35087:62;35084:88;;;35152:18;;:::i;:::-;35192:10;35188:2;35181:22;;35233:9;35227:16;35219:6;35212:32;35298:2;35287:9;35283:18;35277:25;35272:2;35264:6;35260:15;35253:50;35357:2;35346:9;35342:18;35336:25;35331:2;35323:6;35319:15;35312:50;35416:2;35405:9;35401:18;35395:25;35390:2;35382:6;35378:15;35371:50;35476:3;35465:9;35461:19;35455:26;35449:3;35441:6;35437:16;35430:52;35537:3;35526:9;35522:19;35516:26;35510:3;35502:6;35498:16;35491:52;35586:3;35575:9;35571:19;35565:26;35600:31;35625:5;35600:31;:::i;:::-;35659:3;35647:16;;35640:31;35651:6;34817:885;-1:-1:-1;;;34817:885:31:o;36440:209::-;36478:3;36506:18;36559:2;36552:5;36548:14;36586:2;36577:7;36574:15;36571:41;;36592:18;;:::i;:::-;36641:1;36628:15;;36440:209;-1:-1:-1;;;36440:209:31:o;37324:287::-;37453:3;37491:6;37485:13;37507:66;37566:6;37561:3;37554:4;37546:6;37542:17;37507:66;:::i;:::-;37589:16;;;;;37324:287;-1:-1:-1;;37324:287:31:o;38858:184::-;38910:77;38907:1;38900:88;39007:4;39004:1;38997:15;39031:4;39028:1;39021:15;39405:219;39554:2;39543:9;39536:21;39517:4;39574:44;39614:2;39603:9;39599:18;39591:6;39574:44;:::i
Swarm Source
ipfs://fdb6ba83f728e5392faff07831cb2795776710580c3d03aa2c41f045bbc8d358
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.