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
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 41147357 | 440 days ago | IN | 0 WEMIX | 0.531379 |
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; ConfigSnapshot memory snapshot = _getBridgeSnapshot(); _processBridgeTransfer(snapshot, BridgeMessage(account, msg.value), true); _claimReward(stakingInfo); } function requestReceive( uint64 srcNonce, BridgeMessage 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 requestWithdrawFee(uint256 amount) public override returns (uint256[] memory withdrawalIds) { address _feeAccount = feeAccount; require(_msgSender() == _feeAccount || _msgSender() == owner(), "only fee account"); StakingInfo memory _stakingInfo = stakingInfo; INCPStaking staking = INCPStaking(_stakingInfo.stake_contract); (uint8[] memory ncpIds, uint128[] memory tmp) = _determineUnstakePid(_stakingInfo, uint128(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]] = address(this); emit RequestFeeWithdrawal(_feeAccount, ncpIds[i], tmp[i], tmpAmount); } assembly { withdrawalIds := tmp } } function completeWithrawFee(uint256 ncpId, uint256 withdrawalId) public override { require(filterWithdrawalId[withdrawalId] == address(this), "withdrawalId filter"); delete filterWithdrawalId[withdrawalId]; address _feeAccount = feeAccount; INCPStaking staking = INCPStaking(stakingInfo.stake_contract); uint256 amount = staking.withdrawalNFT().getWithdrawalRequestInfo(withdrawalId).amount; uint256 beforeBalance = address(this).balance; staking.withdraw( ncpId, withdrawalId, payable( address(this) ) ); require(address(this).balance - beforeBalance == amount, "withdraw amount"); emit CompleteFeeWithdrawal(_feeAccount, ncpId, withdrawalId); _trySendValueCatchFail(payable(_feeAccount), amount); } function _processBridgeTransfer( ConfigSnapshot memory snapshot, BridgeMessage memory msgBridge, bool applyingFee ) internal { 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; } _trySendValueCatchFail(payable(feeAccount), feeAmount); } snapshot.localAsset.bridgeTotalLocked += uint128(msgBridge.amount); _updateAssetInfo(snapshot.localAsset); uint64 _localNonce = _useLocalNonce(); emit ToRemote(_localNonce, msgBridge.account, msgBridge.amount, feeAmount); _stake(msgBridge.amount); } 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, BridgeMessage 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(BridgeMessage 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, withdrawalId, payable( address(this) ) ); 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 BridgeMessage { address account; uint256 amount; } enum BrigeMessegeType { NoneType, ToRemote, ToOrigin, Sync } struct RemoteFeeOracle { address oracleAddress; } 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 view returns (bool filtered); function filterWithdrawalId(uint256 withdrawalId) external view returns (address account); function remoteOracle() external view returns(address); 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 setRemoteOracle(address _remoteOracle) 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, BridgeMessage memory msgToOrigin, Sig[] memory sigs ) external view returns (address[] memory signers); function recoversToRemoteMessage( uint64 nonce, BridgeMessage 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); event RequestFeeWithdrawal(address indexed account, uint256 indexed ncpId, uint256 nftId, uint256 amount); event CompleteFeeWithdrawal(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, BridgeMessage memory msgBridge, Sig[] memory sigs ) external returns (uint256[] memory withdrawalIds); function completeReceive(uint256 ncpId, uint256 withdrawalId) external; function claimReward() external; function sync() external payable; function requestWithdrawFee(uint256 amount) external returns (uint256[] memory withdrawalIds); function completeWithrawFee(uint256 ncpId, uint256 withdrawalId) external ; } 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, BridgeMessage 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; address public override remoteOracle; 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 setRemoteOracle(address _remoteOracle) public override onlyOwner { remoteOracle = _remoteOracle; } function getSrcBridgeContractInfo() external view override returns (BridgeContractInfo memory) { return pairBridgeInfo; } function getStakingInfo() external view override returns (StakingInfo memory) { return stakingInfo; } function getFeeConfig() external view override returns (FeeConfig memory) { return feeConfig; } function getBridgeAmountConfig() external view override returns (BridgeAmountConfig memory) { return bridgeAmountConfig; } function getLocalAsset() external view override 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, BridgeMessage 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, BridgeMessage memory msgToRemote, Sig[] memory sigs ) internal view { checkQuorum( recoversToRemoteMessage(nonce, msgToRemote, sigs) ); } function recoversToOriginMessage( uint64 nonce, BridgeMessage 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, BridgeMessage 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":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"ncpId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"CompleteFeeWithdrawal","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":"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":"RequestFeeWithdrawal","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":[{"internalType":"uint256","name":"ncpId","type":"uint256"},{"internalType":"uint256","name":"withdrawalId","type":"uint256"}],"name":"completeWithrawFee","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 BridgeMessage","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":"struct BridgeMessage","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":"remoteOracle","outputs":[{"internalType":"address","name":"","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 BridgeMessage","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":"uint256","name":"amount","type":"uint256"}],"name":"requestWithdrawFee","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":[{"internalType":"address","name":"_remoteOracle","type":"address"}],"name":"setRemoteOracle","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
60806040523480156200001157600080fd5b50604051620064633803806200646383398101604081905262000034916200062c565b6200003f336200007c565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e5805460ff19169055620000748282620000c6565b50506200074c565b6000620000976000546201000090046001600160a01b031690565b9050620000a481620001fd565b15620000b757620000b781600062000214565b620000c28262000272565b5050565b600054610100900460ff1615808015620000e75750600054600160ff909116105b80620001035750303b15801562000103575060005460ff166001145b6200016c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000190576000805461ff0019166101001790555b6200019b336200007c565b620001a682620002d0565b620001b1836200007c565b8015620001f8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006200020a82620003a7565b5460ff1692915050565b6200022182600062000415565b6200022e81600162000415565b806001600160a01b0316826001600160a01b03167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b600080546001600160a01b038381166201000081810262010000600160b01b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b90565b620002da62000472565b80516001600160a01b0316620003245760405162461bcd60e51b815260206004820152600e60248201526d1cdd185ad94818dbdb9d1c9858dd60921b604482015260640162000163565b806020015151600114620003645760405162461bcd60e51b81526020600482015260066024820152656e637049647360d01b604482015260640162000163565b8051600480546001600160a01b0319166001600160a01b039092169190911781556020808301518051849392620003a192600592910190620004d7565b50505050565b604080516001600160a01b03831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b918101919091526000906200040f9060600160405160208183030381529060405280519060200120620002cd60201b60201c565b92915050565b6001600160a01b03821615620000c25760006200043283620003a7565b805490915082151560ff909116151503620004605760405163053db68960e51b815260040160405180910390fd5b805482151560ff199091161790555050565b6000546001600160a01b0362010000909104163314620004d55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000163565b565b82805482825590600052602060002090601f01602090048101928215620005725791602002820160005b838211156200054157835183826101000a81548160ff021916908360ff160217905550926020019260010160208160000104928301926001030262000501565b8015620005705782816101000a81549060ff021916905560010160208160000104928301926001030262000541565b505b506200058092915062000584565b5090565b5b8082111562000580576000815560010162000585565b80516001600160a01b0381168114620005b357600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620005f357620005f3620005b8565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006245762000624620005b8565b604052919050565b600080604083850312156200064057600080fd5b6200064b836200059b565b602084810151919350906001600160401b03808211156200066b57600080fd5b90850190604082880312156200068057600080fd5b6200068a620005ce565b62000695836200059b565b81528383015182811115620006a957600080fd5b80840193505087601f840112620006bf57600080fd5b825182811115620006d457620006d4620005b8565b8060051b9250620006e7858401620005f9565b818152928401850192858101908a8511156200070257600080fd5b948601945b8486101562000736578551925060ff83168314620007255760008081fd5b828252948601949086019062000707565b8087850152505050809450505050509250929050565b615d07806200075c6000396000f3fe6080604052600436106103385760003560e01c806375dc7d8c116101b0578063b71c1179116100ec578063d1b4ae3a11610095578063e7bd37391161006f578063e7bd373914610be7578063f2fde38b14610c07578063f86276e614610c27578063fff6cae914610c4757600080fd5b8063d1b4ae3a14610b87578063d2a45ab514610ba7578063defb794e14610bc757600080fd5b8063c298ffa8116100c6578063c298ffa814610b1a578063c34b44a014610b3a578063ce0a7e7a14610b5a57600080fd5b8063b71c117914610ad2578063b88a802f14610ae5578063be83f92d14610afa57600080fd5b806394cf795e11610159578063aac132de11610133578063aac132de14610a43578063ac9650d814610a63578063b05e6a3514610a90578063b40cd21d14610ab057600080fd5b806394cf795e146109d65780639bed25d8146109eb578063a8edb3d114610a0057600080fd5b80638456cb591161018a5780638456cb59146109705780638da5cb5b14610985578063930ccaa6146109b657600080fd5b806375dc7d8c146108195780637df73e2714610839578063812db1be1461089e57600080fd5b80635c975abb1161027f57806363c724f7116102285780636dbf2fa0116102025780636dbf2fa0146107815780636f760d6c146107a2578063715018a6146107cf578063715bfe51146107e457600080fd5b806363c724f71461070757806363fa5c481461072757806365e17c9d1461075457600080fd5b8063615f32ed11610259578063615f32ed14610697578063628484ab146106b7578063629866b2146106e757600080fd5b80635c975abb146106155780635d3341851461063a5780635fbbc0d21461065a57600080fd5b80632ca3998d116102e15780634535b113116102bb5780634535b113146105315780634b023cf8146105515780635982fd201461057157600080fd5b80632ca3998d146104685780633f4ba83a146104de57806341f684f3146104f357600080fd5b80631ee93647116103125780631ee93647146103d65780632079fb9a146104035780632465e58e1461044857600080fd5b8063014e95ba1461034c57806308f496dd1461037c57806313cb35911461039c57600080fd5b3661034757610345610c4f565b005b600080fd5b34801561035857600080fd5b5061036261271081565b60405163ffffffff90911681526020015b60405180910390f35b34801561038857600080fd5b50610345610397366004614fa9565b610c90565b3480156103a857600080fd5b50600e546103bd9067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610373565b3480156103e257600080fd5b506103f66103f1366004615175565b610ca6565b604051610373919061521b565b34801561040f57600080fd5b5061042361041e366004615269565b610e7d565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610373565b34801561045457600080fd5b50610345610463366004614fa9565b610ed9565b34801561047457600080fd5b50604080518082018252600080825260209182015281518083018352600d546fffffffffffffffffffffffffffffffff8082168084527001000000000000000000000000000000009092048116928401928352845191825291519091169181019190915201610373565b3480156104ea57600080fd5b50610345610f28565b3480156104ff57600080fd5b507ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b545b604051908152602001610373565b34801561053d57600080fd5b5061034561054c366004615296565b610fc3565b34801561055d57600080fd5b5061034561056c366004614fa9565b611102565b34801561057d57600080fd5b506106086040805160608101825260008082526020820181905291810191909152506040805160608101825260035463ffffffff81168252640100000000810473ffffffffffffffffffffffffffffffffffffffff1660208301527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169181019190915290565b60405161037391906152d6565b34801561062157600080fd5b5061062a611151565b6040519015158152602001610373565b34801561064657600080fd5b506103456106553660046153d4565b611183565b34801561066657600080fd5b5061066f61132a565b6040805182518152602080840151908201529181015163ffffffff1690820152606001610373565b3480156106a357600080fd5b506103456106b2366004615424565b61137f565b3480156106c357600080fd5b5061062a6106d2366004615269565b600f6020526000908152604090205460ff1681565b3480156106f357600080fd5b50610345610702366004615479565b6114da565b34801561071357600080fd5b50610345610722366004614fa9565b6115ff565b34801561073357600080fd5b506011546104239073ffffffffffffffffffffffffffffffffffffffff1681565b34801561076057600080fd5b506001546104239073ffffffffffffffffffffffffffffffffffffffff1681565b61079461078f3660046154ea565b61169d565b6040516103739291906155e1565b3480156107ae57600080fd5b506107c26107bd366004615175565b611721565b60405161037391906155fc565b3480156107db57600080fd5b506103456118ff565b3480156107f057600080fd5b506108046107ff366004615269565b611911565b60408051928352602083019190915201610373565b34801561082557600080fd5b50610523610834366004615269565b6119a4565b34801561084557600080fd5b5061062a610854366004614fa9565b73ffffffffffffffffffffffffffffffffffffffff1660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205460ff1690565b3480156108aa57600080fd5b5061092760408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526009548152600a546020820152600b546fffffffffffffffffffffffffffffffff808216938301939093527001000000000000000000000000000000009004909116606082015290565b604080518251815260208084015190820152828201516fffffffffffffffffffffffffffffffff9081169282019290925260609283015190911691810191909152608001610373565b34801561097c57600080fd5b506103456119df565b34801561099157600080fd5b5060005462010000900473ffffffffffffffffffffffffffffffffffffffff16610423565b3480156109c257600080fd5b506103456109d1366004615634565b611a7a565b3480156109e257600080fd5b506103f6611db4565b3480156109f757600080fd5b50610345611e42565b348015610a0c57600080fd5b50610423610a1b366004615269565b60106020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610a4f57600080fd5b5061062a610a5e366004614fa9565b611e4d565b348015610a6f57600080fd5b50610a83610a7e366004615656565b611e62565b60405161037391906156cb565b348015610a9c57600080fd5b50610345610aab36600461574d565b611f4a565b348015610abc57600080fd5b50610ac5612162565b6040516103739190615791565b610345610ae0366004614fa9565b612218565b348015610af157600080fd5b50610345612304565b348015610b0657600080fd5b50610345610b15366004614fa9565b612390565b348015610b2657600080fd5b50610345610b35366004615802565b6123a3565b348015610b4657600080fd5b50610345610b55366004614fa9565b612620565b348015610b6657600080fd5b506002546104239073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b9357600080fd5b50610345610ba2366004614fa9565b6126be565b348015610bb357600080fd5b506103f6610bc2366004615175565b61270d565b348015610bd357600080fd5b50610345610be2366004615634565b6128da565b348015610bf357600080fd5b506103f6610c0236600461589c565b6128f0565b348015610c1357600080fd5b50610345610c22366004614fa9565b612abd565b348015610c3357600080fd5b506107c2610c42366004615269565b612b71565b610345613079565b610c57611151565b15610c8e576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b610c9861321f565b610ca36000826132a7565b50565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff87168385015292519092600091610d0b918491600191899101615918565b604051602081830303815290604052805190602001209050835167ffffffffffffffff811115610d3d57610d3d614fe3565b604051908082528060200260200182016040528015610d66578160200160208202803683370190505b50925060005b8451811015610e7357600182868381518110610d8a57610d8a615996565b602002602001015160000151878481518110610da857610da8615996565b602002602001015160200151888581518110610dc657610dc6615996565b60200260200101516040015160405160008152602001604052604051610e08949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610e2a573d6000803e3d6000fd5b50505060206040510351848281518110610e4657610e46615996565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610d6c565b5050509392505050565b60007ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b8281548110610eb157610eb1615996565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1692915050565b610ee161321f565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610f3133611e4d565b80610f85575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610fbb576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8e61331b565b610fcb61321f565b61271063ffffffff16816040015163ffffffff16111561104c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f666565207261746500000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6020810151815111156110bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6665652072616e676500000000000000000000000000000000000000000000006044820152606401611043565b8051600655602081015160075560400151600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091179055565b61110a61321f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061117e7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e55460ff1690565b905090565b600054610100900460ff16158080156111a35750600054600160ff909116105b806111bd5750303b1580156111bd575060005460ff166001145b611249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611043565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156112a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6112b0336133b7565b6112b98261137f565b6112c2836133b7565b801561132557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b61135460405180606001604052806000815260200160008152602001600063ffffffff1681525090565b50604080516060810182526006548152600754602082015260085463ffffffff169181019190915290565b61138761321f565b805173ffffffffffffffffffffffffffffffffffffffff16611405576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b6520636f6e74726163740000000000000000000000000000000000006044820152606401611043565b806020015151600114611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e637049647300000000000000000000000000000000000000000000000000006044820152606401611043565b8051600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117815560208083015180518493926114d492600592910190614ecc565b50505050565b6114e261321f565b805161154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f627269646765206d696e000000000000000000000000000000000000000000006044820152606401611043565b60208101518151106115b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6272696467652072616e676500000000000000000000000000000000000000006044820152606401611043565b80516009556020810151600a5560408101516060909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600b55565b61160833611e4d565b8061165c575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611692576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca36000826133f8565b600060606116a961321f565b8573ffffffffffffffffffffffffffffffffffffffff168585856040516116d19291906159c5565b60006040518083038185875af1925050503d806000811461170e576040519150601f19603f3d011682016040523d82523d6000602084013e611713565b606091505b509150915094509492505050565b606061172b610c4f565b67ffffffffffffffff84166000908152600f602052604090205460ff16156117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f737263206e6f6e636500000000000000000000000000000000000000000000006044820152606401611043565b67ffffffffffffffff84166000908152600f6020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556117f961346c565b905061180781868686613572565b60408201526118158461362a565b9150611856816040015180516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526118f695808601939192908301828280156118e857602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116118b95790505b505050505081525050613a6c565b50509392505050565b61190761321f565b610c8e60006133b7565b6040805160608082018352600654825260075460208084019190915260085463ffffffff168385015283516080810185526009548152600a5491810191909152600b546fffffffffffffffffffffffffffffffff80821695830195909552700100000000000000000000000000000000900490931690830152600091829161199b91859190613bf7565b91509150915091565b604080516060810182526006548152600754602082015260085463ffffffff16918101919091526000906119d9908390613c8d565b92915050565b6119e833611e4d565b80611a3c575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611a72576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8e613cc7565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff163014611b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401611043565b600081815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001546004805483517f83453945000000000000000000000000000000000000000000000000000000008152935173ffffffffffffffffffffffffffffffffffffffff938416969190931694909385936383453945938281019392829003018187875af1158015611bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd791906159d5565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b8152600401611c1191815260200190565b60e060405180830381865afa158015611c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5291906159f2565b606001516040517f0ad58d2f0000000000000000000000000000000000000000000000000000000081526004810187905260248101869052306044820152909150479073ffffffffffffffffffffffffffffffffffffffff841690630ad58d2f90606401600060405180830381600087803b158015611cd057600080fd5b505af1158015611ce4573d6000803e3d6000fd5b50505050818147611cf59190615aab565b14611d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401611043565b84868573ffffffffffffffffffffffffffffffffffffffff167f7c74c89791d36692f3e6c457d3c7c0a625dd51bf7eb6a6a903008dfbd0c8ca8c60405160405180910390a4611dab8483613d40565b50505050505050565b60607ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b805480602002602001604051908101604052809291908181526020018280548015611e3857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611e0d575b5050505050905090565b610c8e3360006132a7565b6000611e5882613f50565b5460ff1692915050565b6040805160008152602081019091526060908267ffffffffffffffff811115611e8d57611e8d614fe3565b604051908082528060200260200182016040528015611ec057816020015b6060815260200190600190039081611eab5790505b50915060005b83811015611f4257611f1d30868684818110611ee457611ee4615996565b9050602002810190611ef69190615abe565b85604051602001611f0993929190615b23565b604051602081830303815290604052613fbb565b838281518110611f2f57611f2f615996565b6020908102919091010152600101611ec6565b505092915050565b611f5261321f565b602081015173ffffffffffffffffffffffffffffffffffffffff16611fd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f62726964676520616464726573730000000000000000000000000000000000006044820152606401611043565b805163ffffffff16600003612044576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f62726964676520636861696e20696400000000000000000000000000000000006044820152606401611043565b604081015167ffffffffffffffff16156120ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f627269646765206e6f6e636500000000000000000000000000000000000000006044820152606401611043565b805160038054602084015160409094015167ffffffffffffffff1678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff909516640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921663ffffffff909416939093171792909216179055565b6040805180820190915260008152606060208201526040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815293949293838601939092919083018282801561220a57602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116121db5790505b505050505081525050905090565b612220610c4f565b73ffffffffffffffffffffffffffffffffffffffff811661223e5750335b600061224861346c565b90506122808160405180604001604052808573ffffffffffffffffffffffffffffffffffffffff168152602001348152506001613fe7565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815261132595808601939192908301828280156118e8576000918252602091829020805460ff1684529082028301929091600191018084116118b9579050505050505081525050613a6c565b61230c610c4f565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152610ca395808601939192908301828280156118e8576000918252602091829020805460ff1684529082028301929091600191018084116118b9579050505050505081525050613a6c565b61239861321f565b610ca38160006132a7565b805160017ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b546123d5911c6001615b4a565b81101561243e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f71756f72756d00000000000000000000000000000000000000000000000000006044820152606401611043565b600181111561253d576000612454600183615aab565b905060005b8181101561253a578361246d826001615b4a565b8151811061247d5761247d615996565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168482815181106124ad576124ad615996565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612532576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f417363656e64696e67204f7264657200000000000000000000000000000000006044820152606401611043565b600101612459565b50505b7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b60005b828110156114d45781600085838151811061257e5761257e615996565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff16612618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c6964207369676e65720000000000000000000000000000000000006044820152606401611043565b600101612561565b61262933611e4d565b8061267d575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6126b3576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca38160006133f8565b6126c661321f565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff87168385015292519092600091612772918491600291899101615918565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156127a4576127a4614fe3565b6040519080825280602002602001820160405280156127cd578160200160208202803683370190505b50925060005b8451811015610e73576001828683815181106127f1576127f1615996565b60200260200101516000015187848151811061280f5761280f615996565b60200260200101516020015188858151811061282d5761282d615996565b6020026020010151604001516040516000815260200160405260405161286f949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612891573d6000803e3d6000fd5b505050602060405103518482815181106128ad576128ad615996565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016127d3565b6128e2610c4f565b6128ec82826141aa565b5050565b60408051606080820183526003805463ffffffff81168452640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208085019190915267ffffffffffffffff881684860152935191936000926129559285929091899101615b5d565b604051602081830303815290604052805190602001209050835167ffffffffffffffff81111561298757612987614fe3565b6040519080825280602002602001820160405280156129b0578160200160208202803683370190505b50925060005b8451811015610e73576001828683815181106129d4576129d4615996565b6020026020010151600001518784815181106129f2576129f2615996565b602002602001015160200151888581518110612a1057612a10615996565b60200260200101516040015160405160008152602001604052604051612a52949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612a74573d6000803e3d6000fd5b50505060206040510351848281518110612a9057612a90615996565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016129b6565b612ac561321f565b73ffffffffffffffffffffffffffffffffffffffff8116612b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401611043565b610ca3816133b7565b60015460609073ffffffffffffffffffffffffffffffffffffffff1633811480612be4575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612c4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6f6e6c7920666565206163636f756e74000000000000000000000000000000006044820152606401611043565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815260009580860193919290830182828015612cdb57602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612cac5790505b50505091909252505081519192506000905080612cf884886144da565b915091506000805b835181101561306c57828181518110612d1b57612d1b615996565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e09818858381518110612d6557612d65615996565b6020026020010151868481518110612d7f57612d7f615996565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af1158015612e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e289190615bba565b838281518110612e3a57612e3a615996565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff1660106000858481518110612e9a57612e9a615996565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614612f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401611043565b3060106000858481518110612f5b57612f5b615996565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838181518110612fd357612fd3615996565b602002602001015160ff168773ffffffffffffffffffffffffffffffffffffffff167f9704c90fe671db4764d6a63750b9fa5c553824edb7df6027b79034dbc754346285848151811061302857613028615996565b60200260200101518560405161305c9291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a3600101612d00565b5090979650505050505050565b613081610c4f565b600061308b61346c565b60025490915073ffffffffffffffffffffffffffffffffffffffff16338114613112576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110439060208082526004908201527f73796e6300000000000000000000000000000000000000000000000000000000604082015260600190565b61311b346144f3565b3482604001516000018181516131319190615bd3565b6fffffffffffffffffffffffffffffffff169052506040820151602001805134919061315e908390615bd3565b6fffffffffffffffffffffffffffffffff1690525060408201516131b39080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006131bd6146da565b90508173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f6a28c316db1c85974981164e2be540ab36fb82b391d0dfda369f948d1474de173460405161321291815260200190565b60405180910390a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff62010000909104163314610c8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611043565b6132b2826000614723565b6132bd816001614723565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b6133236147c0565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166133df81611e4d565b156133ef576133ef8160006132a7565b6128ec826147fe565b61340382600061487c565b61340e81600161487c565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f9d188613a1a9a2ea26521bec252487f1739a344d8ffe6ef61cd7bca567d8f3d160405160405180910390a35050565b6134d06040805160c08101825260006060808301828152608080850184905260a08501849052908452845190810185528281526020808201849052818601849052918101839052818401528351808501855282815290810191909152909182015290565b604080516080810182526009548152600a54602080830191909152600b546fffffffffffffffffffffffffffffffff80821684860152700100000000000000000000000000000000918290048116606080860191909152868401949094528451938401855260065484526007548484015260085463ffffffff168486015292855283518085018552600d54808516825291909104909216908201529082015290565b6040805180820190915260008082526020820152613591848484614a37565b6020830151604086015180516135a8908390615bfc565b6fffffffffffffffffffffffffffffffff16905250825160208085015160405190815273ffffffffffffffffffffffffffffffffffffffff9092169167ffffffffffffffff8716917fca798eef187f833f790884379ed453edfc01901535dc3083866f8446dc25f0f8910160405180910390a35060408401515b949350505050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815260609560009594938186019390918301828280156136bf57602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116136905790505b50505050508152505090506000816000015190506000806136e48487602001516144da565b915091506000805b8351811015613a605782818151811061370757613707615996565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e0981885838151811061375157613751615996565b602002602001015186848151811061376b5761376b615996565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af11580156137f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138149190615bba565b83828151811061382657613826615996565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff166010600085848151811061388657613886615996565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614613930576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401611043565b87600001516010600085848151811061394b5761394b615996565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508381815181106139c3576139c3615996565b602002602001015160ff16886000015173ffffffffffffffffffffffffffffffffffffffff167f4833244c0517cc1688428ff8842d0c253c9cea94b95f61d91a680203b55ebf01858481518110613a1c57613a1c615996565b602002602001015185604051613a509291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a36001016136ec565b50909695505050505050565b60025460009073ffffffffffffffffffffffffffffffffffffffff1680613aef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f73796e63207a65726f00000000000000000000000000000000000000000000006044820152606401611043565b825173ffffffffffffffffffffffffffffffffffffffff821631925060005b846020015151811015613bd5578173ffffffffffffffffffffffffffffffffffffffff1663ddd5e1b286602001518381518110613b4d57613b4d615996565b6020026020010151856040518363ffffffff1660e01b8152600401613b9792919060ff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015613bb157600080fd5b505af1158015613bc5573d6000803e3d6000fd5b505060019092019150613b0e9050565b506136228373ffffffffffffffffffffffffffffffffffffffff841631615aab565b600080613c048584614a45565b613c0e8585613c8d565b9050808511613c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401611043565b613c838186615aab565b9150935093915050565b6040810151815161271063ffffffff90921684029190910490811015613cb1575080515b81602001518111156119d9575060200151919050565b613ccf610c4f565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2583361338d565b600081471015613dac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6661696c2073656e642076616c756500000000000000000000000000000000006044820152606401611043565b60405173ffffffffffffffffffffffffffffffffffffffff8416908390600081818185875af1925050503d8060008114613e02576040519150601f19603f3d011682016040523d82523d6000602084013e613e07565b606091505b505080915050806119d9578273ffffffffffffffffffffffffffffffffffffffff167f7a8da3fbf14e43fbfd79d8ce7ab913a13000dbbd248e9442988476e9e4b94cd883604051613e5a91815260200190565b60405180910390a26000805462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d8060008114613ed9576040519150601f19603f3d011682016040523d82523d6000602084013e613ede565b606091505b5050905080613f49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6661696c20616d6f756e742063617463680000000000000000000000000000006044820152606401611043565b5092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b918101919091526000906119d9906060016040516020818303038152906040528051906020012090565b6060613fe08383604051806060016040528060278152602001615cab60279139614b1e565b9392505050565b6000613ffb83602001518560200151614a45565b81156140b25761401383602001518560000151613c8d565b905080836020015111614082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401611043565b60208301805182900390526001546140b09073ffffffffffffffffffffffffffffffffffffffff1682613d40565b505b6020830151604085015180516140c9908390615bd3565b6fffffffffffffffffffffffffffffffff16905250604084015161411e9080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006141286146da565b9050836000015173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f87c8e141595387353b9f5800de2510b7678d07b38c7e01c29ab619d7938e639686602001518560405161418e929190918252602082015260400190565b60405180910390a36141a384602001516144f3565b5050505050565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff1680614236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401611043565b600082815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556004805482517f83453945000000000000000000000000000000000000000000000000000000008152925173ffffffffffffffffffffffffffffffffffffffff909116949385936383453945938181019391829003018187875af11580156142d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142fd91906159d5565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b815260040161433791815260200190565b60e060405180830381865afa158015614354573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061437891906159f2565b606001516040517f0ad58d2f0000000000000000000000000000000000000000000000000000000081526004810187905260248101869052306044820152909150479073ffffffffffffffffffffffffffffffffffffffff841690630ad58d2f90606401600060405180830381600087803b1580156143f657600080fd5b505af115801561440a573d6000803e3d6000fd5b5050505081814761441b9190615aab565b14614482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401611043565b61448c8483613d40565b5084868573ffffffffffffffffffffffffffffffffffffffff167f56938cd8bd3b7e9e03d3414d2307365bc79aa14190fc2b22e7119ad2ba26c48160405160405180910390a4505050505050565b6060806144e78484614ba3565b915091505b9250929050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526000958086019391929083018282801561458457602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116145555790505b505050919092525050815191925060009050806145a18486614ba3565b9150915060005b82518110156146d2578373ffffffffffffffffffffffffffffffffffffffff16636366ebe38383815181106145df576145df615996565b60200260200101516fffffffffffffffffffffffffffffffff1685848151811061460b5761460b615996565b602002602001015185858151811061462557614625615996565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260ff90921660048301526fffffffffffffffffffffffffffffffff166024820152306044820152600060648201819052608482015260a4016000604051808303818588803b1580156146ad57600080fd5b505af11580156146c1573d6000803e3d6000fd5b5050600190930192506145a8915050565b505050505050565b600e805460009167ffffffffffffffff90911690826146f883615c25565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905090565b73ffffffffffffffffffffffffffffffffffffffff8216156128ec57600061474a83613f50565b805490915082151560ff909116151503614790576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80548215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790555050565b6147c8611151565b610c8e576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b73ffffffffffffffffffffffffffffffffffffffff8216156128ec5773ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205481151560ff90911615150361491e576040517fd4be6f0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215801591909117909155614a0d577ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b80546001810182556000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555050565b6128ec7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b83614c8b565b611325610b3584848461270d565b8051821015614ab0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d696e696d756d000000000000000000000000000000000000000000000000006044820152606401611043565b81816020015110156128ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d6178696d756d000000000000000000000000000000000000000000000000006044820152606401611043565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051614b489190615c4c565b600060405180830381855af49150503d8060008114614b83576040519150601f19603f3d011682016040523d82523d6000602084013e614b88565b606091505b5091509150614b9986838387614ded565b9695505050505050565b606080836020015151600114614c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f64656661756c74206e63704964000000000000000000000000000000000000006044820152606401611043565b60208401516040805160018082528183019092529193508160200160208202803683370190505090508281600081518110614c5257614c52615996565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff16815250509250929050565b815460005b818110156114d457838181548110614caa57614caa615996565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff90811690841603614de55783614ce2600184615aab565b81548110614cf257614cf2615996565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848281548110614d2f57614d2f615996565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083805480614d8757614d87615c68565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b600101614c90565b60608315614e83578251600003614e7c5773ffffffffffffffffffffffffffffffffffffffff85163b614e7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611043565b5081613622565b6136228383815115614e985781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110439190615c97565b82805482825590600052602060002090601f01602090048101928215614f625791602002820160005b83821115614f3357835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302614ef5565b8015614f605782816101000a81549060ff0219169055600101602081600001049283019260010302614f33565b505b50614f6e929150614f72565b5090565b5b80821115614f6e5760008155600101614f73565b73ffffffffffffffffffffffffffffffffffffffff81168114610ca357600080fd5b600060208284031215614fbb57600080fd5b8135613fe081614f87565b803567ffffffffffffffff81168114614fde57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561503557615035614fe3565b60405290565b6040805190810167ffffffffffffffff8111828210171561503557615035614fe3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156150a5576150a5614fe3565b604052919050565b600067ffffffffffffffff8211156150c7576150c7614fe3565b5060051b60200190565b803560ff81168114614fde57600080fd5b600082601f8301126150f357600080fd5b81356020615108615103836150ad565b61505e565b8281526060928302850182019282820191908785111561512757600080fd5b8387015b8581101561306c5781818a0312156151435760008081fd5b61514b615012565b615154826150d1565b8152818601358682015260408083013590820152845292840192810161512b565b6000806000838503608081121561518b57600080fd5b61519485614fc6565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0820112156151c657600080fd5b506151cf61503b565b60208501356151dd81614f87565b8152604085013560208201529150606084013567ffffffffffffffff81111561520557600080fd5b615211868287016150e2565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b81811015613a6057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101615237565b60006020828403121561527b57600080fd5b5035919050565b803563ffffffff81168114614fde57600080fd5b6000606082840312156152a857600080fd5b6152b0615012565b82358152602083013560208201526152ca60408401615282565b60408201529392505050565b815163ffffffff16815260208083015173ffffffffffffffffffffffffffffffffffffffff169082015260408083015167ffffffffffffffff1690820152606081016119d9565b60006040828403121561532f57600080fd5b61533761503b565b9050813561534481614f87565b815260208281013567ffffffffffffffff81111561536157600080fd5b8301601f8101851361537257600080fd5b8035615380615103826150ad565b81815260059190911b8201830190838101908783111561539f57600080fd5b928401925b828410156153c4576153b5846150d1565b825292840192908401906153a4565b8085870152505050505092915050565b600080604083850312156153e757600080fd5b82356153f281614f87565b9150602083013567ffffffffffffffff81111561540e57600080fd5b61541a8582860161531d565b9150509250929050565b60006020828403121561543657600080fd5b813567ffffffffffffffff81111561544d57600080fd5b6136228482850161531d565b80356fffffffffffffffffffffffffffffffff81168114614fde57600080fd5b60006080828403121561548b57600080fd5b6040516080810181811067ffffffffffffffff821117156154ae576154ae614fe3565b806040525082358152602083013560208201526154cd60408401615459565b60408201526154de60608401615459565b60608201529392505050565b6000806000806060858703121561550057600080fd5b843561550b81614f87565b935060208501359250604085013567ffffffffffffffff8082111561552f57600080fd5b818701915087601f83011261554357600080fd5b81358181111561555257600080fd5b88602082850101111561556457600080fd5b95989497505060200194505050565b60005b8381101561558e578181015183820152602001615576565b50506000910152565b600081518084526155af816020860160208601615573565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b82151581526040602082015260006136226040830184615597565b6020808252825182820181905260009190848201906040850190845b81811015613a6057835183529284019291840191600101615618565b6000806040838503121561564757600080fd5b50508035926020909101359150565b6000806020838503121561566957600080fd5b823567ffffffffffffffff8082111561568157600080fd5b818501915085601f83011261569557600080fd5b8135818111156156a457600080fd5b8660208260051b85010111156156b957600080fd5b60209290920196919550909350505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015615740577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261572e858351615597565b945092850192908501906001016156f4565b5092979650505050505050565b60006060828403121561575f57600080fd5b615767615012565b61577083615282565b8152602083013561578081614f87565b60208201526152ca60408401614fc6565b6020808252825173ffffffffffffffffffffffffffffffffffffffff16828201528281015160408084015280516060840181905260009291820190839060808601905b808310156157f757835160ff1682529284019260019290920191908401906157d4565b509695505050505050565b6000602080838503121561581557600080fd5b823567ffffffffffffffff81111561582c57600080fd5b8301601f8101851361583d57600080fd5b803561584b615103826150ad565b81815260059190911b8201830190838101908783111561586a57600080fd5b928401925b8284101561589157833561588281614f87565b8252928401929084019061586f565b979650505050505050565b6000806000606084860312156158b157600080fd5b6158ba84614fc6565b925060208401359150604084013567ffffffffffffffff81111561520557600080fd5b60048110615914577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260c0810161596760608301856158dd565b73ffffffffffffffffffffffffffffffffffffffff8351166080830152602083015160a0830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183823760009101908152919050565b6000602082840312156159e757600080fd5b8151613fe081614f87565b600060e08284031215615a0457600080fd5b60405160e0810181811067ffffffffffffffff82111715615a2757615a27614fe3565b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c0830151615a7081614f87565b60c08201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156119d9576119d9615a7c565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112615af357600080fd5b83018035915067ffffffffffffffff821115615b0e57600080fd5b6020019150368190038213156144ec57600080fd5b828482376000838201600081528351615b40818360208801615573565b0195945050505050565b808201808211156119d9576119d9615a7c565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260a08101615bac60608301856158dd565b826080830152949350505050565b600060208284031215615bcc57600080fd5b5051919050565b6fffffffffffffffffffffffffffffffff818116838216019080821115613f4957613f49615a7c565b6fffffffffffffffffffffffffffffffff828116828216039080821115613f4957613f49615a7c565b600067ffffffffffffffff808316818103615c4257615c42615a7c565b6001019392505050565b60008251615c5e818460208701615573565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000613fe0602083018461559756fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220dae8ce0fdf8a19b8ef61f228069ce65a82d9928b390af40043f3f60f60e9a4b664736f6c634300081700330000000000000000000000007d76ae60dcc2fdb57d3924024e2ad940b76ef81f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000006af09e1a3c886dd8560bf4cabd65db16ea2724d8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000029
Deployed Bytecode
0x6080604052600436106103385760003560e01c806375dc7d8c116101b0578063b71c1179116100ec578063d1b4ae3a11610095578063e7bd37391161006f578063e7bd373914610be7578063f2fde38b14610c07578063f86276e614610c27578063fff6cae914610c4757600080fd5b8063d1b4ae3a14610b87578063d2a45ab514610ba7578063defb794e14610bc757600080fd5b8063c298ffa8116100c6578063c298ffa814610b1a578063c34b44a014610b3a578063ce0a7e7a14610b5a57600080fd5b8063b71c117914610ad2578063b88a802f14610ae5578063be83f92d14610afa57600080fd5b806394cf795e11610159578063aac132de11610133578063aac132de14610a43578063ac9650d814610a63578063b05e6a3514610a90578063b40cd21d14610ab057600080fd5b806394cf795e146109d65780639bed25d8146109eb578063a8edb3d114610a0057600080fd5b80638456cb591161018a5780638456cb59146109705780638da5cb5b14610985578063930ccaa6146109b657600080fd5b806375dc7d8c146108195780637df73e2714610839578063812db1be1461089e57600080fd5b80635c975abb1161027f57806363c724f7116102285780636dbf2fa0116102025780636dbf2fa0146107815780636f760d6c146107a2578063715018a6146107cf578063715bfe51146107e457600080fd5b806363c724f71461070757806363fa5c481461072757806365e17c9d1461075457600080fd5b8063615f32ed11610259578063615f32ed14610697578063628484ab146106b7578063629866b2146106e757600080fd5b80635c975abb146106155780635d3341851461063a5780635fbbc0d21461065a57600080fd5b80632ca3998d116102e15780634535b113116102bb5780634535b113146105315780634b023cf8146105515780635982fd201461057157600080fd5b80632ca3998d146104685780633f4ba83a146104de57806341f684f3146104f357600080fd5b80631ee93647116103125780631ee93647146103d65780632079fb9a146104035780632465e58e1461044857600080fd5b8063014e95ba1461034c57806308f496dd1461037c57806313cb35911461039c57600080fd5b3661034757610345610c4f565b005b600080fd5b34801561035857600080fd5b5061036261271081565b60405163ffffffff90911681526020015b60405180910390f35b34801561038857600080fd5b50610345610397366004614fa9565b610c90565b3480156103a857600080fd5b50600e546103bd9067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610373565b3480156103e257600080fd5b506103f66103f1366004615175565b610ca6565b604051610373919061521b565b34801561040f57600080fd5b5061042361041e366004615269565b610e7d565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610373565b34801561045457600080fd5b50610345610463366004614fa9565b610ed9565b34801561047457600080fd5b50604080518082018252600080825260209182015281518083018352600d546fffffffffffffffffffffffffffffffff8082168084527001000000000000000000000000000000009092048116928401928352845191825291519091169181019190915201610373565b3480156104ea57600080fd5b50610345610f28565b3480156104ff57600080fd5b507ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b545b604051908152602001610373565b34801561053d57600080fd5b5061034561054c366004615296565b610fc3565b34801561055d57600080fd5b5061034561056c366004614fa9565b611102565b34801561057d57600080fd5b506106086040805160608101825260008082526020820181905291810191909152506040805160608101825260035463ffffffff81168252640100000000810473ffffffffffffffffffffffffffffffffffffffff1660208301527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169181019190915290565b60405161037391906152d6565b34801561062157600080fd5b5061062a611151565b6040519015158152602001610373565b34801561064657600080fd5b506103456106553660046153d4565b611183565b34801561066657600080fd5b5061066f61132a565b6040805182518152602080840151908201529181015163ffffffff1690820152606001610373565b3480156106a357600080fd5b506103456106b2366004615424565b61137f565b3480156106c357600080fd5b5061062a6106d2366004615269565b600f6020526000908152604090205460ff1681565b3480156106f357600080fd5b50610345610702366004615479565b6114da565b34801561071357600080fd5b50610345610722366004614fa9565b6115ff565b34801561073357600080fd5b506011546104239073ffffffffffffffffffffffffffffffffffffffff1681565b34801561076057600080fd5b506001546104239073ffffffffffffffffffffffffffffffffffffffff1681565b61079461078f3660046154ea565b61169d565b6040516103739291906155e1565b3480156107ae57600080fd5b506107c26107bd366004615175565b611721565b60405161037391906155fc565b3480156107db57600080fd5b506103456118ff565b3480156107f057600080fd5b506108046107ff366004615269565b611911565b60408051928352602083019190915201610373565b34801561082557600080fd5b50610523610834366004615269565b6119a4565b34801561084557600080fd5b5061062a610854366004614fa9565b73ffffffffffffffffffffffffffffffffffffffff1660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205460ff1690565b3480156108aa57600080fd5b5061092760408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526009548152600a546020820152600b546fffffffffffffffffffffffffffffffff808216938301939093527001000000000000000000000000000000009004909116606082015290565b604080518251815260208084015190820152828201516fffffffffffffffffffffffffffffffff9081169282019290925260609283015190911691810191909152608001610373565b34801561097c57600080fd5b506103456119df565b34801561099157600080fd5b5060005462010000900473ffffffffffffffffffffffffffffffffffffffff16610423565b3480156109c257600080fd5b506103456109d1366004615634565b611a7a565b3480156109e257600080fd5b506103f6611db4565b3480156109f757600080fd5b50610345611e42565b348015610a0c57600080fd5b50610423610a1b366004615269565b60106020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610a4f57600080fd5b5061062a610a5e366004614fa9565b611e4d565b348015610a6f57600080fd5b50610a83610a7e366004615656565b611e62565b60405161037391906156cb565b348015610a9c57600080fd5b50610345610aab36600461574d565b611f4a565b348015610abc57600080fd5b50610ac5612162565b6040516103739190615791565b610345610ae0366004614fa9565b612218565b348015610af157600080fd5b50610345612304565b348015610b0657600080fd5b50610345610b15366004614fa9565b612390565b348015610b2657600080fd5b50610345610b35366004615802565b6123a3565b348015610b4657600080fd5b50610345610b55366004614fa9565b612620565b348015610b6657600080fd5b506002546104239073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b9357600080fd5b50610345610ba2366004614fa9565b6126be565b348015610bb357600080fd5b506103f6610bc2366004615175565b61270d565b348015610bd357600080fd5b50610345610be2366004615634565b6128da565b348015610bf357600080fd5b506103f6610c0236600461589c565b6128f0565b348015610c1357600080fd5b50610345610c22366004614fa9565b612abd565b348015610c3357600080fd5b506107c2610c42366004615269565b612b71565b610345613079565b610c57611151565b15610c8e576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b610c9861321f565b610ca36000826132a7565b50565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff87168385015292519092600091610d0b918491600191899101615918565b604051602081830303815290604052805190602001209050835167ffffffffffffffff811115610d3d57610d3d614fe3565b604051908082528060200260200182016040528015610d66578160200160208202803683370190505b50925060005b8451811015610e7357600182868381518110610d8a57610d8a615996565b602002602001015160000151878481518110610da857610da8615996565b602002602001015160200151888581518110610dc657610dc6615996565b60200260200101516040015160405160008152602001604052604051610e08949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610e2a573d6000803e3d6000fd5b50505060206040510351848281518110610e4657610e46615996565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610d6c565b5050509392505050565b60007ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b8281548110610eb157610eb1615996565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1692915050565b610ee161321f565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610f3133611e4d565b80610f85575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610fbb576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8e61331b565b610fcb61321f565b61271063ffffffff16816040015163ffffffff16111561104c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f666565207261746500000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6020810151815111156110bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6665652072616e676500000000000000000000000000000000000000000000006044820152606401611043565b8051600655602081015160075560400151600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091179055565b61110a61321f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061117e7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e55460ff1690565b905090565b600054610100900460ff16158080156111a35750600054600160ff909116105b806111bd5750303b1580156111bd575060005460ff166001145b611249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611043565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156112a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6112b0336133b7565b6112b98261137f565b6112c2836133b7565b801561132557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b61135460405180606001604052806000815260200160008152602001600063ffffffff1681525090565b50604080516060810182526006548152600754602082015260085463ffffffff169181019190915290565b61138761321f565b805173ffffffffffffffffffffffffffffffffffffffff16611405576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b6520636f6e74726163740000000000000000000000000000000000006044820152606401611043565b806020015151600114611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e637049647300000000000000000000000000000000000000000000000000006044820152606401611043565b8051600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117815560208083015180518493926114d492600592910190614ecc565b50505050565b6114e261321f565b805161154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f627269646765206d696e000000000000000000000000000000000000000000006044820152606401611043565b60208101518151106115b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6272696467652072616e676500000000000000000000000000000000000000006044820152606401611043565b80516009556020810151600a5560408101516060909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600b55565b61160833611e4d565b8061165c575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611692576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca36000826133f8565b600060606116a961321f565b8573ffffffffffffffffffffffffffffffffffffffff168585856040516116d19291906159c5565b60006040518083038185875af1925050503d806000811461170e576040519150601f19603f3d011682016040523d82523d6000602084013e611713565b606091505b509150915094509492505050565b606061172b610c4f565b67ffffffffffffffff84166000908152600f602052604090205460ff16156117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f737263206e6f6e636500000000000000000000000000000000000000000000006044820152606401611043565b67ffffffffffffffff84166000908152600f6020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556117f961346c565b905061180781868686613572565b60408201526118158461362a565b9150611856816040015180516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526118f695808601939192908301828280156118e857602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116118b95790505b505050505081525050613a6c565b50509392505050565b61190761321f565b610c8e60006133b7565b6040805160608082018352600654825260075460208084019190915260085463ffffffff168385015283516080810185526009548152600a5491810191909152600b546fffffffffffffffffffffffffffffffff80821695830195909552700100000000000000000000000000000000900490931690830152600091829161199b91859190613bf7565b91509150915091565b604080516060810182526006548152600754602082015260085463ffffffff16918101919091526000906119d9908390613c8d565b92915050565b6119e833611e4d565b80611a3c575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611a72576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8e613cc7565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff163014611b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401611043565b600081815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001546004805483517f83453945000000000000000000000000000000000000000000000000000000008152935173ffffffffffffffffffffffffffffffffffffffff938416969190931694909385936383453945938281019392829003018187875af1158015611bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd791906159d5565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b8152600401611c1191815260200190565b60e060405180830381865afa158015611c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5291906159f2565b606001516040517f0ad58d2f0000000000000000000000000000000000000000000000000000000081526004810187905260248101869052306044820152909150479073ffffffffffffffffffffffffffffffffffffffff841690630ad58d2f90606401600060405180830381600087803b158015611cd057600080fd5b505af1158015611ce4573d6000803e3d6000fd5b50505050818147611cf59190615aab565b14611d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401611043565b84868573ffffffffffffffffffffffffffffffffffffffff167f7c74c89791d36692f3e6c457d3c7c0a625dd51bf7eb6a6a903008dfbd0c8ca8c60405160405180910390a4611dab8483613d40565b50505050505050565b60607ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b805480602002602001604051908101604052809291908181526020018280548015611e3857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611e0d575b5050505050905090565b610c8e3360006132a7565b6000611e5882613f50565b5460ff1692915050565b6040805160008152602081019091526060908267ffffffffffffffff811115611e8d57611e8d614fe3565b604051908082528060200260200182016040528015611ec057816020015b6060815260200190600190039081611eab5790505b50915060005b83811015611f4257611f1d30868684818110611ee457611ee4615996565b9050602002810190611ef69190615abe565b85604051602001611f0993929190615b23565b604051602081830303815290604052613fbb565b838281518110611f2f57611f2f615996565b6020908102919091010152600101611ec6565b505092915050565b611f5261321f565b602081015173ffffffffffffffffffffffffffffffffffffffff16611fd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f62726964676520616464726573730000000000000000000000000000000000006044820152606401611043565b805163ffffffff16600003612044576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f62726964676520636861696e20696400000000000000000000000000000000006044820152606401611043565b604081015167ffffffffffffffff16156120ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f627269646765206e6f6e636500000000000000000000000000000000000000006044820152606401611043565b805160038054602084015160409094015167ffffffffffffffff1678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff909516640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921663ffffffff909416939093171792909216179055565b6040805180820190915260008152606060208201526040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815293949293838601939092919083018282801561220a57602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116121db5790505b505050505081525050905090565b612220610c4f565b73ffffffffffffffffffffffffffffffffffffffff811661223e5750335b600061224861346c565b90506122808160405180604001604052808573ffffffffffffffffffffffffffffffffffffffff168152602001348152506001613fe7565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815261132595808601939192908301828280156118e8576000918252602091829020805460ff1684529082028301929091600191018084116118b9579050505050505081525050613a6c565b61230c610c4f565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152610ca395808601939192908301828280156118e8576000918252602091829020805460ff1684529082028301929091600191018084116118b9579050505050505081525050613a6c565b61239861321f565b610ca38160006132a7565b805160017ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b546123d5911c6001615b4a565b81101561243e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f71756f72756d00000000000000000000000000000000000000000000000000006044820152606401611043565b600181111561253d576000612454600183615aab565b905060005b8181101561253a578361246d826001615b4a565b8151811061247d5761247d615996565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168482815181106124ad576124ad615996565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612532576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f417363656e64696e67204f7264657200000000000000000000000000000000006044820152606401611043565b600101612459565b50505b7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b60005b828110156114d45781600085838151811061257e5761257e615996565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff16612618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c6964207369676e65720000000000000000000000000000000000006044820152606401611043565b600101612561565b61262933611e4d565b8061267d575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6126b3576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca38160006133f8565b6126c661321f565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff87168385015292519092600091612772918491600291899101615918565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156127a4576127a4614fe3565b6040519080825280602002602001820160405280156127cd578160200160208202803683370190505b50925060005b8451811015610e73576001828683815181106127f1576127f1615996565b60200260200101516000015187848151811061280f5761280f615996565b60200260200101516020015188858151811061282d5761282d615996565b6020026020010151604001516040516000815260200160405260405161286f949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612891573d6000803e3d6000fd5b505050602060405103518482815181106128ad576128ad615996565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016127d3565b6128e2610c4f565b6128ec82826141aa565b5050565b60408051606080820183526003805463ffffffff81168452640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208085019190915267ffffffffffffffff881684860152935191936000926129559285929091899101615b5d565b604051602081830303815290604052805190602001209050835167ffffffffffffffff81111561298757612987614fe3565b6040519080825280602002602001820160405280156129b0578160200160208202803683370190505b50925060005b8451811015610e73576001828683815181106129d4576129d4615996565b6020026020010151600001518784815181106129f2576129f2615996565b602002602001015160200151888581518110612a1057612a10615996565b60200260200101516040015160405160008152602001604052604051612a52949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612a74573d6000803e3d6000fd5b50505060206040510351848281518110612a9057612a90615996565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016129b6565b612ac561321f565b73ffffffffffffffffffffffffffffffffffffffff8116612b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401611043565b610ca3816133b7565b60015460609073ffffffffffffffffffffffffffffffffffffffff1633811480612be4575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612c4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6f6e6c7920666565206163636f756e74000000000000000000000000000000006044820152606401611043565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815260009580860193919290830182828015612cdb57602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612cac5790505b50505091909252505081519192506000905080612cf884886144da565b915091506000805b835181101561306c57828181518110612d1b57612d1b615996565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e09818858381518110612d6557612d65615996565b6020026020010151868481518110612d7f57612d7f615996565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af1158015612e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e289190615bba565b838281518110612e3a57612e3a615996565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff1660106000858481518110612e9a57612e9a615996565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614612f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401611043565b3060106000858481518110612f5b57612f5b615996565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838181518110612fd357612fd3615996565b602002602001015160ff168773ffffffffffffffffffffffffffffffffffffffff167f9704c90fe671db4764d6a63750b9fa5c553824edb7df6027b79034dbc754346285848151811061302857613028615996565b60200260200101518560405161305c9291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a3600101612d00565b5090979650505050505050565b613081610c4f565b600061308b61346c565b60025490915073ffffffffffffffffffffffffffffffffffffffff16338114613112576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110439060208082526004908201527f73796e6300000000000000000000000000000000000000000000000000000000604082015260600190565b61311b346144f3565b3482604001516000018181516131319190615bd3565b6fffffffffffffffffffffffffffffffff169052506040820151602001805134919061315e908390615bd3565b6fffffffffffffffffffffffffffffffff1690525060408201516131b39080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006131bd6146da565b90508173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f6a28c316db1c85974981164e2be540ab36fb82b391d0dfda369f948d1474de173460405161321291815260200190565b60405180910390a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff62010000909104163314610c8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611043565b6132b2826000614723565b6132bd816001614723565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b6133236147c0565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166133df81611e4d565b156133ef576133ef8160006132a7565b6128ec826147fe565b61340382600061487c565b61340e81600161487c565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f9d188613a1a9a2ea26521bec252487f1739a344d8ffe6ef61cd7bca567d8f3d160405160405180910390a35050565b6134d06040805160c08101825260006060808301828152608080850184905260a08501849052908452845190810185528281526020808201849052818601849052918101839052818401528351808501855282815290810191909152909182015290565b604080516080810182526009548152600a54602080830191909152600b546fffffffffffffffffffffffffffffffff80821684860152700100000000000000000000000000000000918290048116606080860191909152868401949094528451938401855260065484526007548484015260085463ffffffff168486015292855283518085018552600d54808516825291909104909216908201529082015290565b6040805180820190915260008082526020820152613591848484614a37565b6020830151604086015180516135a8908390615bfc565b6fffffffffffffffffffffffffffffffff16905250825160208085015160405190815273ffffffffffffffffffffffffffffffffffffffff9092169167ffffffffffffffff8716917fca798eef187f833f790884379ed453edfc01901535dc3083866f8446dc25f0f8910160405180910390a35060408401515b949350505050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815260609560009594938186019390918301828280156136bf57602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116136905790505b50505050508152505090506000816000015190506000806136e48487602001516144da565b915091506000805b8351811015613a605782818151811061370757613707615996565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e0981885838151811061375157613751615996565b602002602001015186848151811061376b5761376b615996565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af11580156137f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138149190615bba565b83828151811061382657613826615996565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff166010600085848151811061388657613886615996565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614613930576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401611043565b87600001516010600085848151811061394b5761394b615996565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508381815181106139c3576139c3615996565b602002602001015160ff16886000015173ffffffffffffffffffffffffffffffffffffffff167f4833244c0517cc1688428ff8842d0c253c9cea94b95f61d91a680203b55ebf01858481518110613a1c57613a1c615996565b602002602001015185604051613a509291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a36001016136ec565b50909695505050505050565b60025460009073ffffffffffffffffffffffffffffffffffffffff1680613aef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f73796e63207a65726f00000000000000000000000000000000000000000000006044820152606401611043565b825173ffffffffffffffffffffffffffffffffffffffff821631925060005b846020015151811015613bd5578173ffffffffffffffffffffffffffffffffffffffff1663ddd5e1b286602001518381518110613b4d57613b4d615996565b6020026020010151856040518363ffffffff1660e01b8152600401613b9792919060ff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015613bb157600080fd5b505af1158015613bc5573d6000803e3d6000fd5b505060019092019150613b0e9050565b506136228373ffffffffffffffffffffffffffffffffffffffff841631615aab565b600080613c048584614a45565b613c0e8585613c8d565b9050808511613c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401611043565b613c838186615aab565b9150935093915050565b6040810151815161271063ffffffff90921684029190910490811015613cb1575080515b81602001518111156119d9575060200151919050565b613ccf610c4f565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2583361338d565b600081471015613dac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6661696c2073656e642076616c756500000000000000000000000000000000006044820152606401611043565b60405173ffffffffffffffffffffffffffffffffffffffff8416908390600081818185875af1925050503d8060008114613e02576040519150601f19603f3d011682016040523d82523d6000602084013e613e07565b606091505b505080915050806119d9578273ffffffffffffffffffffffffffffffffffffffff167f7a8da3fbf14e43fbfd79d8ce7ab913a13000dbbd248e9442988476e9e4b94cd883604051613e5a91815260200190565b60405180910390a26000805462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d8060008114613ed9576040519150601f19603f3d011682016040523d82523d6000602084013e613ede565b606091505b5050905080613f49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6661696c20616d6f756e742063617463680000000000000000000000000000006044820152606401611043565b5092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b918101919091526000906119d9906060016040516020818303038152906040528051906020012090565b6060613fe08383604051806060016040528060278152602001615cab60279139614b1e565b9392505050565b6000613ffb83602001518560200151614a45565b81156140b25761401383602001518560000151613c8d565b905080836020015111614082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401611043565b60208301805182900390526001546140b09073ffffffffffffffffffffffffffffffffffffffff1682613d40565b505b6020830151604085015180516140c9908390615bd3565b6fffffffffffffffffffffffffffffffff16905250604084015161411e9080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006141286146da565b9050836000015173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f87c8e141595387353b9f5800de2510b7678d07b38c7e01c29ab619d7938e639686602001518560405161418e929190918252602082015260400190565b60405180910390a36141a384602001516144f3565b5050505050565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff1680614236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401611043565b600082815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556004805482517f83453945000000000000000000000000000000000000000000000000000000008152925173ffffffffffffffffffffffffffffffffffffffff909116949385936383453945938181019391829003018187875af11580156142d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142fd91906159d5565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b815260040161433791815260200190565b60e060405180830381865afa158015614354573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061437891906159f2565b606001516040517f0ad58d2f0000000000000000000000000000000000000000000000000000000081526004810187905260248101869052306044820152909150479073ffffffffffffffffffffffffffffffffffffffff841690630ad58d2f90606401600060405180830381600087803b1580156143f657600080fd5b505af115801561440a573d6000803e3d6000fd5b5050505081814761441b9190615aab565b14614482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401611043565b61448c8483613d40565b5084868573ffffffffffffffffffffffffffffffffffffffff167f56938cd8bd3b7e9e03d3414d2307365bc79aa14190fc2b22e7119ad2ba26c48160405160405180910390a4505050505050565b6060806144e78484614ba3565b915091505b9250929050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526000958086019391929083018282801561458457602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116145555790505b505050919092525050815191925060009050806145a18486614ba3565b9150915060005b82518110156146d2578373ffffffffffffffffffffffffffffffffffffffff16636366ebe38383815181106145df576145df615996565b60200260200101516fffffffffffffffffffffffffffffffff1685848151811061460b5761460b615996565b602002602001015185858151811061462557614625615996565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260ff90921660048301526fffffffffffffffffffffffffffffffff166024820152306044820152600060648201819052608482015260a4016000604051808303818588803b1580156146ad57600080fd5b505af11580156146c1573d6000803e3d6000fd5b5050600190930192506145a8915050565b505050505050565b600e805460009167ffffffffffffffff90911690826146f883615c25565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905090565b73ffffffffffffffffffffffffffffffffffffffff8216156128ec57600061474a83613f50565b805490915082151560ff909116151503614790576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80548215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790555050565b6147c8611151565b610c8e576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b73ffffffffffffffffffffffffffffffffffffffff8216156128ec5773ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205481151560ff90911615150361491e576040517fd4be6f0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215801591909117909155614a0d577ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b80546001810182556000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555050565b6128ec7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b83614c8b565b611325610b3584848461270d565b8051821015614ab0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d696e696d756d000000000000000000000000000000000000000000000000006044820152606401611043565b81816020015110156128ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d6178696d756d000000000000000000000000000000000000000000000000006044820152606401611043565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051614b489190615c4c565b600060405180830381855af49150503d8060008114614b83576040519150601f19603f3d011682016040523d82523d6000602084013e614b88565b606091505b5091509150614b9986838387614ded565b9695505050505050565b606080836020015151600114614c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f64656661756c74206e63704964000000000000000000000000000000000000006044820152606401611043565b60208401516040805160018082528183019092529193508160200160208202803683370190505090508281600081518110614c5257614c52615996565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff16815250509250929050565b815460005b818110156114d457838181548110614caa57614caa615996565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff90811690841603614de55783614ce2600184615aab565b81548110614cf257614cf2615996565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848281548110614d2f57614d2f615996565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083805480614d8757614d87615c68565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b600101614c90565b60608315614e83578251600003614e7c5773ffffffffffffffffffffffffffffffffffffffff85163b614e7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611043565b5081613622565b6136228383815115614e985781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110439190615c97565b82805482825590600052602060002090601f01602090048101928215614f625791602002820160005b83821115614f3357835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302614ef5565b8015614f605782816101000a81549060ff0219169055600101602081600001049283019260010302614f33565b505b50614f6e929150614f72565b5090565b5b80821115614f6e5760008155600101614f73565b73ffffffffffffffffffffffffffffffffffffffff81168114610ca357600080fd5b600060208284031215614fbb57600080fd5b8135613fe081614f87565b803567ffffffffffffffff81168114614fde57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561503557615035614fe3565b60405290565b6040805190810167ffffffffffffffff8111828210171561503557615035614fe3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156150a5576150a5614fe3565b604052919050565b600067ffffffffffffffff8211156150c7576150c7614fe3565b5060051b60200190565b803560ff81168114614fde57600080fd5b600082601f8301126150f357600080fd5b81356020615108615103836150ad565b61505e565b8281526060928302850182019282820191908785111561512757600080fd5b8387015b8581101561306c5781818a0312156151435760008081fd5b61514b615012565b615154826150d1565b8152818601358682015260408083013590820152845292840192810161512b565b6000806000838503608081121561518b57600080fd5b61519485614fc6565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0820112156151c657600080fd5b506151cf61503b565b60208501356151dd81614f87565b8152604085013560208201529150606084013567ffffffffffffffff81111561520557600080fd5b615211868287016150e2565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b81811015613a6057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101615237565b60006020828403121561527b57600080fd5b5035919050565b803563ffffffff81168114614fde57600080fd5b6000606082840312156152a857600080fd5b6152b0615012565b82358152602083013560208201526152ca60408401615282565b60408201529392505050565b815163ffffffff16815260208083015173ffffffffffffffffffffffffffffffffffffffff169082015260408083015167ffffffffffffffff1690820152606081016119d9565b60006040828403121561532f57600080fd5b61533761503b565b9050813561534481614f87565b815260208281013567ffffffffffffffff81111561536157600080fd5b8301601f8101851361537257600080fd5b8035615380615103826150ad565b81815260059190911b8201830190838101908783111561539f57600080fd5b928401925b828410156153c4576153b5846150d1565b825292840192908401906153a4565b8085870152505050505092915050565b600080604083850312156153e757600080fd5b82356153f281614f87565b9150602083013567ffffffffffffffff81111561540e57600080fd5b61541a8582860161531d565b9150509250929050565b60006020828403121561543657600080fd5b813567ffffffffffffffff81111561544d57600080fd5b6136228482850161531d565b80356fffffffffffffffffffffffffffffffff81168114614fde57600080fd5b60006080828403121561548b57600080fd5b6040516080810181811067ffffffffffffffff821117156154ae576154ae614fe3565b806040525082358152602083013560208201526154cd60408401615459565b60408201526154de60608401615459565b60608201529392505050565b6000806000806060858703121561550057600080fd5b843561550b81614f87565b935060208501359250604085013567ffffffffffffffff8082111561552f57600080fd5b818701915087601f83011261554357600080fd5b81358181111561555257600080fd5b88602082850101111561556457600080fd5b95989497505060200194505050565b60005b8381101561558e578181015183820152602001615576565b50506000910152565b600081518084526155af816020860160208601615573565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b82151581526040602082015260006136226040830184615597565b6020808252825182820181905260009190848201906040850190845b81811015613a6057835183529284019291840191600101615618565b6000806040838503121561564757600080fd5b50508035926020909101359150565b6000806020838503121561566957600080fd5b823567ffffffffffffffff8082111561568157600080fd5b818501915085601f83011261569557600080fd5b8135818111156156a457600080fd5b8660208260051b85010111156156b957600080fd5b60209290920196919550909350505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015615740577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261572e858351615597565b945092850192908501906001016156f4565b5092979650505050505050565b60006060828403121561575f57600080fd5b615767615012565b61577083615282565b8152602083013561578081614f87565b60208201526152ca60408401614fc6565b6020808252825173ffffffffffffffffffffffffffffffffffffffff16828201528281015160408084015280516060840181905260009291820190839060808601905b808310156157f757835160ff1682529284019260019290920191908401906157d4565b509695505050505050565b6000602080838503121561581557600080fd5b823567ffffffffffffffff81111561582c57600080fd5b8301601f8101851361583d57600080fd5b803561584b615103826150ad565b81815260059190911b8201830190838101908783111561586a57600080fd5b928401925b8284101561589157833561588281614f87565b8252928401929084019061586f565b979650505050505050565b6000806000606084860312156158b157600080fd5b6158ba84614fc6565b925060208401359150604084013567ffffffffffffffff81111561520557600080fd5b60048110615914577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260c0810161596760608301856158dd565b73ffffffffffffffffffffffffffffffffffffffff8351166080830152602083015160a0830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183823760009101908152919050565b6000602082840312156159e757600080fd5b8151613fe081614f87565b600060e08284031215615a0457600080fd5b60405160e0810181811067ffffffffffffffff82111715615a2757615a27614fe3565b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c0830151615a7081614f87565b60c08201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156119d9576119d9615a7c565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112615af357600080fd5b83018035915067ffffffffffffffff821115615b0e57600080fd5b6020019150368190038213156144ec57600080fd5b828482376000838201600081528351615b40818360208801615573565b0195945050505050565b808201808211156119d9576119d9615a7c565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260a08101615bac60608301856158dd565b826080830152949350505050565b600060208284031215615bcc57600080fd5b5051919050565b6fffffffffffffffffffffffffffffffff818116838216019080821115613f4957613f49615a7c565b6fffffffffffffffffffffffffffffffff828116828216039080821115613f4957613f49615a7c565b600067ffffffffffffffff808316818103615c4257615c42615a7c565b6001019392505050565b60008251615c5e818460208701615573565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000613fe0602083018461559756fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220dae8ce0fdf8a19b8ef61f228069ce65a82d9928b390af40043f3f60f60e9a4b664736f6c63430008170033
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:9337:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1917:19:26;:17;:19::i;:::-;309:9337: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;3360:583:4;;;;;;;;;;-1:-1:-1;3360:583:4;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1959:124:27:-;;;;;;;;;;-1:-1:-1;1959:124:27;;;;;:::i;:::-;;:::i;:::-;;;5408:42:31;5396:55;;;5378:74;;5366:2;5351:18;1959:124:27;5232:226:31;1025:115:4;;;;;;;;;;-1:-1:-1;1025:115:4;;;;;:::i;:::-;;:::i;2907:97::-;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;2984:17:4;;;;;;;2991:10;2984:17;;;;;;;;;;;;;;;;;;;;2907:97;;5716:41:31;;;5799:24;;5795:33;;;5773:20;;;5766:63;;;;5636:18;2907:97:4;5463:372:31;2355:70:25;;;;;;;;;;;;;:::i;2089:117:27:-;;;;;;;;;;-1:-1:-1;1806:66:27;2161:38;2089:117;;;5986:25:31;;;5974:2;5959:18;2089:117:27;5840:177:31;1768:238:4;;;;;;;;;;-1:-1:-1;1768:238:4;;;;;:::i;:::-;;:::i;909:111::-;;;;;;;;;;-1:-1:-1;909:111:4;;;;;:::i;:::-;;:::i;2448:121::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;2545:21:4;;;;;;;;2552:14;2545:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;2448:121;;;;;;;;:::i;2293:86:26:-;;;;;;;;;;;;;:::i;:::-;;;7370:14:31;;7363:22;7345:41;;7333:2;7318:18;2293:86:26;7205:187:31;562:249:5;;;;;;;;;;-1:-1:-1;562:249:5;;;;;:::i;:::-;;:::i;2680:95:4:-;;;;;;;;;;;;;:::i;:::-;;;;9157:13:31;;9139:32;;9227:4;9215:17;;;9209:24;9187:20;;;9180:54;9282:17;;;9276:24;9302:10;9272:41;9250:20;;;9243:71;9127:2;9112:18;2680:95:4;8939:381:31;1497:265:4;;;;;;;;;;-1:-1:-1;1497:265:4;;;;;:::i;:::-;;:::i;600:76::-;;;;;;;;;;-1:-1:-1;600:76:4;;;;;:::i;:::-;;;;;;;;;;;;;;;;2012:305;;;;;;;;;;-1:-1:-1;2012:305:4;;;;;:::i;:::-;;:::i;2510:124:27:-;;;;;;;;;;-1:-1:-1;2510:124:27;;;;;:::i;:::-;;:::i;772:36:4:-;;;;;;;;;;-1:-1:-1;772:36:4;;;;;;;;305:25;;;;;;;;;;-1:-1:-1;305:25:4;;;;;;;;1601:229:25;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;1204:589:5:-;;;;;;;;;;-1:-1:-1;1204:589:5;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1815:101:23:-;;;;;;;;;;;;;:::i;3010:213:4:-;;;;;;;;;;-1:-1:-1;3010:213:4;;;;;:::i;:::-;;:::i;:::-;;;;13044:25:31;;;13100:2;13085:18;;13078:34;;;;13017:18;3010:213:4;12870:248:31;3228:126:4;;;;;;;;;;-1:-1:-1;3228: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;2780:122:4;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2874:25:4;;;;;;;;2881:18;2874:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2780:122;;;;;13360:13:31;;13342:32;;13430:4;13418:17;;;13412:24;13390:20;;;13383:54;13472:17;;;13466:24;13509:34;13581:21;;;13559:20;;;13552:51;;;;13663:4;13651:17;;;13645:24;13641:33;;;13619:20;;;13612:63;;;;13329:3;13314:19;2780:122:4;13123:558:31;2283:66:25;;;;;;;;;;;;;:::i;1192:85:23:-;;;;;;;;;;-1:-1:-1;1238:7:23;1264:6;;;;;;1192:85;;3784:829:5;;;;;;;;;;-1:-1:-1;3784:829:5;;;;;:::i;:::-;;:::i;2212:149:27:-;;;;;;;;;;;;;:::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;1146:346:4:-;;;;;;;;;;-1:-1:-1;1146:346:4;;;;;:::i;:::-;;:::i;2574:101::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;880:318:5:-;;;;;;:::i;:::-;;:::i;1953: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;;;;;;;;2323:119;;;;;;;;;;-1:-1:-1;2323:119:4;;;;;:::i;:::-;;:::i;4163:583::-;;;;;;;;;;-1:-1:-1;4163:583:4;;;;;:::i;:::-;;:::i;1799:148:5:-;;;;;;;;;;-1:-1:-1;1799:148:5;;;;;:::i;:::-;;:::i;4966:551:4:-;;;;;;;;;;-1:-1:-1;4966:551:4;;;;;:::i;:::-;;:::i;2065:198:23:-;;;;;;;;;;-1:-1:-1;2065:198:23;;;;;:::i;:::-;;:::i;2609:1169:5:-;;;;;;;;;;-1:-1:-1;2609:1169:5;;;;;:::i;:::-;;:::i;2054:549::-;;;:::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;3360:583:4:-;3540:52;;;3504:24;3540:52;;;;;3578:14;3540:52;;;;;;;;;;;;;;;;;;;;3602:23;;3540:52;;;3602:23;3665:61;;3504:24;;-1:-1:-1;;3665:61:4;;3540:52;;;;3714:11;;3665:61;;:::i;:::-;;;;;;;;;;;;;3655:72;;;;;;3636:91;;3762:4;:11;3748:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3748:26:4;;3738:36;;3789:9;3785:152;3802:4;:11;3800:1;:13;3785:152;;;3843:52;3853:8;3863:4;3868:1;3863:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3874:4;3879:1;3874:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3885:4;3890:1;3885:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3843:52;;;;;;;;;;;;;;;;;19669:25:31;;;19742:4;19730:17;;;;19725:2;19710:18;;19703:45;19779:2;19764:18;;19757:34;19822:2;19807:18;;19800:34;19656:3;19641:19;;19442:398;3843:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3830:7;3838:1;3830:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;3921:3;;3785:152;;;;3530:413;;3360:583;;;;;:::o;1959:124:27:-;2012:7;1806:66;2070:5;2038:38;;;;;;;;:::i;:::-;;;;;;;;;;;;;;1959:124;-1:-1:-1;;1959:124:27:o;1025:115:4:-;1085:13:23;:11;:13::i;:::-;1107:11:4::1;:26:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;1025: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;1768:238:4:-:0;1085:13:23;:11;:13::i;:::-;294:5:4::1;1863:27;;:10;:15;;;:27;;;;1855:48;;;::::0;::::1;::::0;;20047:2:31;1855:48:4::1;::::0;::::1;20029:21:31::0;20086:1;20066:18;;;20059:29;20124:10;20104:18;;;20097:38;20152:18;;1855:48:4::1;;;;;;;;;1939:14;::::0;::::1;::::0;1921;;:32:::1;;1913:54;;;::::0;::::1;::::0;;20383:2:31;1913:54:4::1;::::0;::::1;20365:21:31::0;20422:1;20402:18;;;20395:29;20460:11;20440:18;;;20433:39;20489:18;;1913:54:4::1;20181:332:31::0;1913:54:4::1;1977:22:::0;;:9:::1;:22:::0;::::1;::::0;::::1;::::0;;;::::1;;::::0;;;;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;1768:238::o;909:111::-;1085:13:23;:11;:13::i;:::-;989:10:4::1;:24:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;909: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;;;;;;;20720:2:31;3313:201:20;;;20702:21:31;20759:2;20739:18;;;20732:30;20798:34;20778:18;;;20771:62;20869:16;20849:18;;;20842:44;20903:19;;3313:201:20;20518: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;21085:36:31;;3709:14:20;;21073:2:31;21058:18;3709:14:20;;;;;;;3635:99;3257:483;562:249:5;;:::o;2680:95:4:-;2736:16;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;2736:16:4;-1:-1:-1;2756:16:4;;;;;;;;2763:9;2756:16;;;;;;;;;;;;;;;;;;;;;2680:95::o;1497:265::-;1085:13:23;:11;:13::i;:::-;1598:27:4;;:41:::1;;1590:68;;;::::0;::::1;::::0;;21334:2:31;1590:68:4::1;::::0;::::1;21316:21:31::0;21373:2;21353:18;;;21346:30;21412:16;21392:18;;;21385:44;21446:18;;1590:68:4::1;21132:338:31::0;1590:68:4::1;1676:12;:19;;;:26;1706:1;1676:31;1668:50;;;::::0;::::1;::::0;;21677:2:31;1668:50:4::1;::::0;::::1;21659:21:31::0;21716:1;21696:18;;;21689:29;21754:8;21734:18;;;21727:36;21780:18;;1668:50:4::1;21475:329:31::0;1668:50:4::1;1729: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;;;;1497:265:4:o;2012:305::-;1085:13:23;:11;:13::i;:::-;2134:23:4;;2126:50:::1;;;::::0;::::1;::::0;;22011:2:31;2126:50:4::1;::::0;::::1;21993:21:31::0;22050:2;22030:18;;;22023:30;22089:12;22069:18;;;22062:40;22119:18;;2126:50:4::1;21809:334:31::0;2126:50:4::1;2220:23;::::0;::::1;::::0;2194;;:49:::1;2186:74;;;::::0;::::1;::::0;;22350:2:31;2186:74:4::1;::::0;::::1;22332:21:31::0;22389:2;22369:18;;;22362:30;22428:14;22408:18;;;22401:42;22460:18;;2186:74:4::1;22148:336:31::0;2186:74:4::1;2270: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;;2012: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;1204:589:5:-;1366:30;1917:19:26;:17;:19::i;:::-;1417:24:5::1;::::0;::::1;;::::0;;;:14:::1;:24;::::0;;;;;::::1;;1416:25;1408:47;;;::::0;::::1;::::0;;22967:2:31;1408:47:5::1;::::0;::::1;22949:21:31::0;23006:1;22986:18;;;22979:29;23044:11;23024:18;;;23017:39;23073:18;;1408:47:5::1;22765:332:31::0;1408:47:5::1;1465:24;::::0;::::1;;::::0;;;:14:::1;:24;::::0;;;;:31;;;::::1;1492:4;1465:31;::::0;;1540:20:::1;:18;:20::i;:::-;1507:53;;1593:58;1615:8;1625;1635:9;1646:4;1593:21;:58::i;:::-;1571:19;::::0;::::1;:80:::0;1677:26:::1;1693:9:::0;1677:15:::1;:26::i;:::-;1661:42;;1714:37;1731:8;:19;;;6144:23:4::0;;;;;;;;;;;;;;;;:10;:23;6070:104;1714:37:5::1;1761:25;::::0;;;;::::1;::::0;;1774:11:::1;1761: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;:::-;;1398:395;1204:589:::0;;;;;:::o;1815:101:23:-;1085:13;:11;:13::i;:::-;1879:30:::1;1906:1;1879:18;:30::i;3010:213:4:-:0;3152:64;;;;;;;;;3186:9;3152:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;3197:18;3152:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3092:22;;;;3152:64;;3178:6;;3152:64;:25;:64::i;:::-;3145:71;;;;3010:213;;;:::o;3228:126::-;3320:27;;;;;;;;3337:9;3320:27;;;;;;;;;;;;;;;;;;;;3284:17;;3320:27;;3329:6;;3320:8;:27::i;:::-;3313:34;3228:126;-1:-1:-1;;3228: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;3784:829:5:-:0;3883:32;;;;:18;:32;;;;;;:49;:32;3927:4;3883:49;3875:81;;;;;;;23304:2:31;3875:81:5;;;23286:21:31;23343:2;23323:18;;;23316:30;23382:21;23362:18;;;23355:49;23421:18;;3875:81:5;23102:343:31;3875:81:5;3973:32;;;;:18;:32;;;;;;;;3966:39;;;;;;;4037:10;4092:11;:26;;4146:23;;;;;;;3966:39;4037:10;;;;4092:26;;;;;3973:32;;4092:26;;4146:21;;:23;;;;3973:32;4146:23;;;;;3973:32;4092:26;4146:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;;;4195:12;4146:62;;;;;;;;;;;;;5986:25:31;;5974:2;5959:18;;5840:177;4146:62:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:69;;;4280:109;;;;;;;;24837:25:31;;;24878:18;;;24871:34;;;4372:4:5;24921:18:31;;;24914:83;4146:69:5;;-1:-1:-1;4249:21:5;;4280:16;;;;;;24810:18:31;;4280:109:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4448:6;4431:13;4407:21;:37;;;;:::i;:::-;:47;4399:75;;;;;;;25532:2:31;4399:75:5;;;25514:21:31;25571:2;25551:18;;;25544:30;25610:17;25590:18;;;25583:45;25645:18;;4399:75:5;25330:339:31;4399:75:5;4531:12;4524:5;4511:11;4489:55;;;;;;;;;;;;4554:52;4585:11;4599:6;4554:22;:52::i;:::-;;3865:748;;;;3784:829;;:::o;2212:149:27:-;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;1146:346:4:-;1085:13:23;:11;:13::i;:::-;1260:22:4::1;::::0;::::1;::::0;:36:::1;;1252:63;;;::::0;::::1;::::0;;27242:2:31;1252:63:4::1;::::0;::::1;27224:21:31::0;27281:2;27261:18;;;27254:30;27320:16;27300:18;;;27293:44;27354:18;;1252:63:4::1;27040:338:31::0;1252:63:4::1;1333:23:::0;;:28:::1;;:23;:28:::0;1325:56:::1;;;::::0;::::1;::::0;;27585:2:31;1325:56:4::1;::::0;::::1;27567:21:31::0;27624:2;27604:18;;;27597:30;27663:17;27643:18;;;27636:45;27698:18;;1325:56:4::1;27383:339:31::0;1325:56:4::1;1399:21;::::0;::::1;::::0;:26:::1;;::::0;1391:51:::1;;;::::0;::::1;::::0;;27929:2:31;1391:51:4::1;::::0;::::1;27911:21:31::0;27968:2;27948:18;;;27941:30;28007:14;27987:18;;;27980:42;28039:18;;1391:51:4::1;27727:336:31::0;1391:51:4::1;1453: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;;1146:346::o;2574:101::-;-1:-1:-1;;;;;;;;;;;;;;;;;2654:18:4;;;;;;;;2661:11;2654:18;;;;;;;;;;;;;;;;;;;;;;;;;;;2661:11;;2654:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2574:101;:::o;880:318: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:30;1053:20;:18;:20::i;:::-;1020:53;;1083:73;1106:8;1116:33;;;;;;;;1130:7;1116:33;;;;;;1139:9;1116:33;;::::0;1151:4:::1;1083:22;:73::i;:::-;1166:25;::::0;;;;::::1;::::0;;1179:11:::1;1166: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;1953:95::-:0;1917:19:26;:17;:19::i;:::-;2016:25:5::1;::::0;;;;::::1;::::0;;2029:11:::1;2016: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;;;;;;;28400:2:31;2913:75:27;;;28382:21:31;28439:1;28419:18;;;28412:29;28477:8;28457:18;;;28450:36;28503:18;;2913:75:27;28198: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;;;;;;;28734:2:31;3145:55:27;;;28716:21:31;28773:2;28753:18;;;28746:30;28812:17;28792:18;;;28785:45;28847:18;;3145:55:27;28532: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;;;;;;;29078:2:31;3398:51:27;;;29060:21:31;29117:2;29097:18;;;29090:30;29156:16;29136:18;;;29129:44;29190:18;;3398:51:27;28876: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;2323:119:4:-:0;1085:13:23;:11;:13::i;:::-;2407:12:4::1;:28:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;2323:119::o;4163:583::-;4343:52;;;4307:24;4343:52;;;;;4381:14;4343:52;;;;;;;;;;;;;;;;;;;;4405:23;;4343:52;;;4405:23;4468:61;;4307:24;;-1:-1:-1;;4468:61:4;;4343:52;;4490:25;;4517:11;;4468:61;;:::i;:::-;;;;;;;;;;;;;4458:72;;;;;;4439:91;;4565:4;:11;4551:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4551:26:4;;4541:36;;4592:9;4588:152;4605:4;:11;4603:1;:13;4588:152;;;4646:52;4656:8;4666:4;4671:1;4666:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4677:4;4682:1;4677:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4688:4;4693:1;4688:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4646:52;;;;;;;;;;;;;;;;;19669:25:31;;;19742:4;19730:17;;;;19725:2;19710:18;;19703:45;19779:2;19764:18;;19757:34;19822:2;19807:18;;19800:34;19656:3;19641:19;;19442:398;4646:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4633:7;4641:1;4633:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;4724:3;;4588:152;;1799:148:5;1917:19:26;:17;:19::i;:::-;1903:37:5::1;1920:5;1927:12;1903:16;:37::i;:::-;1799:148:::0;;:::o;4966:551:4:-;5124:52;;;5088:24;5124:52;;;;;5162:14;5124:52;;;;;;;;;;;;;;;;;;;;;5186:23;;5124:52;;;5186:23;5249:52;;5088:24;;-1:-1:-1;;5249:52:4;;5124;;5162:14;;5294:6;;5249:52;;:::i;:::-;;;;;;;;;;;;;5239:63;;;;;;5220:82;;5336:4;:11;5322:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5322:26:4;;5312:36;;5363:9;5359:152;5376:4;:11;5374:1;:13;5359:152;;;5417:52;5427:8;5437:4;5442:1;5437:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5448:4;5453:1;5448:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5459:4;5464:1;5459:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5417:52;;;;;;;;;;;;;;;;;19669:25:31;;;19742:4;19730:17;;;;19725:2;19710:18;;19703:45;19779:2;19764:18;;19757:34;19822:2;19807:18;;19800:34;19656:3;19641:19;;19442:398;5417:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5404:7;5412:1;5404:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;5495:3;;5359:152;;2065:198:23;1085:13;:11;:13::i;:::-;2153:22:::1;::::0;::::1;2145:73;;;::::0;::::1;::::0;;29894:2:31;2145:73:23::1;::::0;::::1;29876:21:31::0;29933:2;29913:18;;;29906:30;29972:34;29952:18;;;29945:62;30043:8;30023:18;;;30016:36;30069:19;;2145:73:23::1;29692:402:31::0;2145:73:23::1;2228:28;2247:8;2228:18;:28::i;2609:1169:5:-:0;2742:10;;2678:30;;2742:10;;734::2;2770:27:5;;;:54;;-1:-1:-1;1238:7:23;1264:6;;;;;;2801:23:5;;734:10:2;2801:23:5;;;2770:54;2762:83;;;;;;;30301:2:31;2762:83:5;;;30283:21:31;30340:2;30320:18;;;30313:30;30379:18;30359;;;30352:46;30415:18;;2762:83:5;30099:340:31;2762:83:5;2856:45;;;;;;;;2890:11;2856:45;;;;;;;;;;;;;;;;;;;;;;;;;:31;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2856:45:5;;;;-1:-1:-1;;2945:27:5;;2856:45;;-1:-1:-1;2911:19:5;;-1:-1:-1;2911:19:5;3031:51;2856:45;3074:6;3031:20;:51::i;:::-;2983:99;;;;3093:17;3125:9;3121:609;3138:6;:13;3136:1;:15;3121:609;;;3184:3;3188:1;3184:6;;;;;;;;:::i;:::-;;;;;;;3172:18;;;;3222:7;:23;;;3263:6;3270:1;3263:9;;;;;;;;:::i;:::-;;;;;;;3307:6;3314:1;3307:9;;;;;;;;:::i;:::-;;;;;;;;;;;3222:278;;;;;;;;;;30761:4:31;30749:17;;;3222:278:5;;;30731:36:31;30803:17;;30783:18;;;30776:45;30837:18;;;30830:34;;;3404:4:5;30880:18:31;;;30873:83;3434:5:5;30972:19:31;;;30965:51;;;31032:19;;;31025:51;30703:19;;3222:278:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3205:3;3209:1;3205:6;;;;;;;;:::i;:::-;;;;;;:296;;;;;;;;;;;3562:1;3524:40;;:18;:26;3543:3;3547:1;3543:6;;;;;;;;:::i;:::-;;;;;;;;;;;;3524:26;;;;;;;;;;;;-1:-1:-1;3524:26:5;;;;:40;3516:65;;;;;;;31478:2:31;3516:65:5;;;31460:21:31;31517:2;31497:18;;;31490:30;31556:14;31536:18;;;31529:42;31588:18;;3516:65:5;31276:336:31;3516:65:5;3632:4;3595:18;:26;3614:3;3618:1;3614:6;;;;;;;;:::i;:::-;;;;;;;3595:26;;;;;;;;;;;;;;:42;;;;;;;;;;;;;;;;;;3690:6;3697:1;3690:9;;;;;;;;:::i;:::-;;;;;;;3656:63;;3677:11;3656:63;;;3701:3;3705:1;3701:6;;;;;;;;:::i;:::-;;;;;;;3709:9;3656:63;;;;;;31821:34:31;31809:47;;;;31791:66;;31888:2;31873:18;;31866:34;31779:2;31764:18;;31617:289;3656:63:5;;;;;;;;3153:3;;3121:609;;;-1:-1:-1;3767:3:5;;2609:1169;-1:-1:-1;;;;;;;2609:1169:5:o;2054:549::-;1917:19:26;:17;:19::i;:::-;2120:30:5::1;2153:20;:18;:20::i;:::-;2206:11;::::0;2120:53;;-1:-1:-1;2206:11:5::1;;2236:10;:26:::0;::::1;2228:43;;;;;;;;;;;32113:2:31::0;32095:21;;;32152:1;32132:18;;;32125:29;32190:6;32185:2;32170:18;;32163:34;32229:2;32214:18;;31911:327;2228:43:5::1;2282:17;2289:9;2282:6;:17::i;:::-;2359:9;2310:8;:19;;;:37;;:59;;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;2379:19:5::1;::::0;::::1;::::0;:42:::1;;:64:::0;;2433:9:::1;::::0;2379:42;:64:::1;::::0;2433:9;;2379:64:::1;:::i;:::-;;;::::0;;-1:-1:-1;2471:19:5::1;::::0;::::1;::::0;2454:37:::1;::::0;6144:23:4;;;;;;;;;;;;;;;;:10;:23;6070:104;2454:37:5::1;2502:18;2523:16;:14;:16::i;:::-;2502:37;;2572:12;2554:42;;2559:11;2554:42;;;2586:9;2554:42;;;;5986:25:31::0;;5974:2;5959:18;;5840:177;2554:42:5::1;;;;;;;;2110:493;;;2054:549::o:0;1350:130:23:-;1238:7;1264:6;1413:23;1264:6;;;;;734:10:2;1413:23:23;1405:68;;;;;;;32647:2:31;1405:68:23;;;32629:21:31;;;32666:18;;;32659:30;32725:34;32705:18;;;32698:62;32777:18;;1405:68:23;32445: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;5408:42:31;5396:55;;;5378:74;;5366:2;5351: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;5706:232:4:-;5759:30;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5759:30:4;5801:48;;;;;;;;5831:18;5801:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:27;;;:48;;;;5859:30;;;;;;;5880:9;5859:30;;;;;;;;;;;;;;;;;;;;5899:32;;;;;;;5921:10;5899:32;;;;;;;;;;;;;;;;;:19;;;:32;5801:8;5706:232::o;6083:462:5:-;-1:-1:-1;;;;;;;;;;;;;;;;;6297:49:5;6320:8;6330:9;6341:4;6297:22;:49::i;:::-;6406:16;;;;6357:19;;;;:66;;;;6406:16;;6357:66;:::i;:::-;;;;;-1:-1:-1;6466:17:5;;6485:16;;;;;6439:63;;5986:25:31;;;6439:63:5;;;;;;;;;;;5959:18:31;6439:63:5;;;;;;;-1:-1:-1;6519:19:5;;;;6083:462;;;;;;;:::o;6551:1091::-;6668:45;;;;;;;;6702:11;6668:45;;;;;;;;;;;;;;;;;;;;;;;;;6626:30;;6668:31;;:45;6702:11;6668:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6723:19;6757:12;:27;;;6723:62;;6796:21;6819:20;6843:61;6864:12;6886:9;:16;;;6843:20;:61::i;:::-;6795:109;;;;6915:17;6947:9;6943:612;6960:6;:13;6958:1;:15;6943:612;;;7006:3;7010:1;7006:6;;;;;;;;:::i;:::-;;;;;;;6994:18;;;;7043:7;:23;;;7084:6;7091:1;7084:9;;;;;;;;:::i;:::-;;;;;;;7128:6;7135:1;7128:9;;;;;;;;:::i;:::-;;;;;;;;;;;7043:278;;;;;;;;;;30761:4:31;30749:17;;;7043:278:5;;;30731:36:31;30803:17;;30783:18;;;30776:45;30837:18;;;30830:34;;;7225:4:5;30880:18:31;;;30873:83;7255:5:5;30972:19:31;;;30965:51;;;31032:19;;;31025:51;30703:19;;7043:278:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7026:3;7030:1;7026:6;;;;;;;;:::i;:::-;;;;;;:296;;;;;;;;;;;7383:1;7345:40;;:18;:26;7364:3;7368:1;7364:6;;;;;;;;:::i;:::-;;;;;;;;;;;;7345:26;;;;;;;;;;;;-1:-1:-1;7345:26:5;;;;:40;7337:65;;;;;;;31478:2:31;7337:65:5;;;31460:21:31;31517:2;31497:18;;;31490:30;31556:14;31536:18;;;31529:42;31588:18;;7337:65:5;31276:336:31;7337:65:5;7445:9;:17;;;7416:18;:26;7435:3;7439:1;7435:6;;;;;;;;:::i;:::-;;;;;;;7416:26;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;7515:6;7522:1;7515:9;;;;;;;;:::i;:::-;;;;;;;7481:63;;7496:9;:17;;;7481:63;;;7526:3;7530:1;7526:6;;;;;;;;:::i;:::-;;;;;;;7534:9;7481:63;;;;;;31821:34:31;31809:47;;;;31791:66;;31888:2;31873:18;;31866:34;31779:2;31764:18;;31617:289;7481:63:5;;;;;;;;6975:3;;6943:612;;;-1:-1:-1;7631:3:5;;6551:1091;-1:-1:-1;;;;;;6551:1091:5:o;9091:553::-;9220:11;;9164:21;;9220:11;;;9241:48;;;;;;;33213:2:31;9241:48:5;;;33195:21:31;33252:1;33232:18;;;33225:29;33290:11;33270:18;;;33263:39;33319:18;;9241:48:5;33011:332:31;9241:48:5;9334:27;;9389:20;;;;;-1:-1:-1;9300:19:5;9420:126;9437:12;:19;;;:26;9435:1;:28;9420:126;;;9484:7;:13;;;9498:12;:19;;;9518:1;9498:22;;;;;;;;:::i;:::-;;;;;;;9522:12;9484:51;;;;;;;;;;;;;;;33550:4:31;33538:17;;;;33520:36;;33604:42;33592:55;33587:2;33572:18;;33565:83;33508:2;33493:18;;33348:306;9484:51:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9465:3:5;;;;;-1:-1:-1;9420:126:5;;-1:-1:-1;9420:126:5;;-1:-1:-1;9601:36:5;9624:13;9601:20;;;;:36;:::i;6662:441:4:-;6842:22;6866:17;6895:55;6922:6;6930:19;6895:26;:55::i;:::-;6972:28;6981:6;6989:10;6972:8;:28::i;:::-;6960:40;;7027:9;7018:6;:18;7010:41;;;;;;;33861:2:31;7010:41:4;;;33843:21:31;33900:2;33880:18;;;33873:30;33939:12;33919:18;;;33912:40;33969:18;;7010:41:4;33659:334:31;7010:41:4;7078:18;7087:9;7078:6;:18;:::i;:::-;7061:35;;6662:441;;;;;;:::o;7109:316::-;7256:15;;;;7309:14;;294:5;7247:35;:24;;;;;:35;;;;;7297:26;;7294:57;;;-1:-1:-1;7337:14:4;;7294:57;7376:10;:14;;;7364:9;:26;7361:57;;;-1:-1:-1;7404:14:4;;;;7109:316;-1:-1:-1;7109: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;6180:476:4;6287:12;6344:6;6319:21;:31;;6311:59;;;;;;;34389:2:31;6311:59:4;;;34371:21:31;34428:2;34408:18;;;34401:30;34467:17;34447:18;;;34440:45;34502:18;;6311:59:4;34187:339:31;6311:59:4;6395:38;;:14;;;;6418:6;;6395:38;;;;6418:6;6395:14;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6381:52;;;;;6448:7;6443:207;;6490:9;6476:32;;;6501:6;6476:32;;;;5986:25:31;;5974:2;5959:18;;5840:177;6476:32:4;;;;;;;;6523:13;1264:6:23;;;;;;;6542:21:4;;6572:6;6542:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6522:65;;;6609:8;6601:38;;;;;;;34943:2:31;6601:38:4;;;34925:21:31;34982:2;34962:18;;;34955:30;35021:19;35001:18;;;34994:47;35058:18;;6601:38:4;34741:341:31;6601:38:4;6457:193;6180:476;;;;:::o;2431:272:25:-;2660:34;;;35291:42:31;35279:55;;2660:34:25;;;35261:74:31;1111:66:25;35351:18:31;;;35344:34;;;;2493:31:25;;2623:73;;35234: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;4619:859:5:-;4782:17;4810:73;4837:9;:16;;;4855:8;:27;;;4810:26;:73::i;:::-;4897:11;4893:289;;;4936:46;4945:9;:16;;;4963:8;:18;;;4936:8;:46::i;:::-;4924:58;;5023:9;5004;:16;;;:28;4996:51;;;;;;;33861:2:31;4996:51:5;;;33843:21:31;33900:2;33880:18;;;33873:30;33939:12;33919:18;;;33912:40;33969:18;;4996:51:5;33659:334:31;4996:51:5;5072:16;;;:29;;;;;;;5148:10;;5117:54;;5148:10;;5092:9;5117:22;:54::i;:::-;;4893:289;5240:16;;;;5191:19;;;;:66;;;;5240:16;;5191:66;:::i;:::-;;;;;-1:-1:-1;5285:19:5;;;;5268:37;;6144:23:4;;;;;;;;;;;;;;;;:10;:23;6070:104;5268:37:5;5315:18;5336:16;:14;:16::i;:::-;5315:37;;5389:9;:17;;;5367:69;;5376:11;5367:69;;;5408:9;:16;;;5426:9;5367:69;;;;;;13044:25:31;;;13100:2;13085:18;;13078:34;13032:2;13017:18;;12870:248;5367:69:5;;;;;;;;5447:24;5454:9;:16;;;5447:6;:24::i;:::-;4772:706;;4619:859;;;:::o;7648:796::-;7730:15;7748:32;;;:18;:32;;;;;;;;;7790:53;;;;;;;23304:2:31;7790:53:5;;;23286:21:31;23343:2;23323:18;;;23316:30;23382:21;23362:18;;;23355:49;23421:18;;7790:53:5;23102:343:31;7790:53:5;7860:32;;;;:18;:32;;;;;;;;7853:39;;;;;;7937:11;:26;;7991:23;;;;;;;7853:39;7937:26;;;;7860:32;7937:26;;7991:21;;:23;;;;;;;;;;7860:32;7937:26;7991:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;;;8040:12;7991:62;;;;;;;;;;;;;5986:25:31;;5974:2;5959:18;;5840:177;7991:62:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:69;;;8125:109;;;;;;;;24837:25:31;;;24878:18;;;24871:34;;;8217:4:5;24921:18:31;;;24914:83;7991:69:5;;-1:-1:-1;8094:21:5;;8125:16;;;;;;24810:18:31;;8125:109:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8293:6;8276:13;8252:21;:37;;;;:::i;:::-;:47;8244:75;;;;;;;25532:2:31;8244:75:5;;;25514:21:31;25571:2;25551:18;;;25544:30;25610:17;25590:18;;;25583:45;25645:18;;8244:75:5;25330:339:31;8244:75:5;8329:48;8360:7;8370:6;8329:22;:48::i;:::-;;8424:12;8417:5;8408:7;8392:45;;;;;;;;;;;;7720:724;;;;7648:796;;:::o;8826:259::-;8959:21;8990:24;9038:40;9057:12;9071:6;9038:18;:40::i;:::-;9031:47;;;;8826:259;;;;;;:::o;5484:593::-;5535:45;;;;;;;;5569:11;5535:45;;;;;;;;;;;;;;;;;;;;;;;;;:31;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5535:45:5;;;;-1:-1:-1;;5624:27:5;;5535:45;;-1:-1:-1;5590:19:5;;-1:-1:-1;5590:19:5;5710:49;5535:45;5751:6;5710:18;:49::i;:::-;5662:97;;;;5773:9;5769:302;5786:6;:13;5784:1;:15;5769:302;;;5820:7;:15;;;5843:3;5847:1;5843:6;;;;;;;;:::i;:::-;;;;;;;5820:240;;5868:6;5875:1;5868:9;;;;;;;;:::i;:::-;;;;;;;5911:3;5915:1;5911:6;;;;;;;;:::i;:::-;;;;;;;;;;;5820:240;;;;;;;;;;35680:4:31;35668:17;;;5820:240:5;;;35650:36:31;35734:34;35722:47;35702:18;;;35695:75;5960:4:5;35786:18:31;;;35779:83;5997:5:5;35878:18:31;;;35871:50;;;35937:19;;;35930:51;35622:19;;5820:240:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5801:3:5;;;;;-1:-1:-1;5769:302:5;;-1:-1:-1;;5769:302:5;;;5525:552;;;;5484:593;:::o;815:88:4:-;884:10;:12;;859:6;;884:12;;;;;859:6;884:12;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;877:19;;815: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;;;;;;;;;;;;;;;;;;;;1799:148:5;;:::o;4047:122:27:-;4121:48;1806:66;4161:6;4121:38;:48::i;4752:208:4:-;4889:64;4902:49;4926:5;4933:11;4946:4;4902:23;:49::i;7431:246::-;7562:23;;:33;-1:-1:-1;7562:33:4;7554:53;;;;;;;36408:2:31;7554:53:4;;;36390:21:31;36447:1;36427:18;;;36420:29;36485:9;36465:18;;;36458:37;36512:18;;7554:53:4;36206:330:31;7554:53:4;7652:6;7625:19;:23;;;:33;;7617:53;;;;;;;36743:2:31;7617:53:4;;;36725:21:31;36782:1;36762:18;;;36755:29;36820:9;36800:18;;;36793:37;36847:18;;7617:53:4;36541: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;8450:370:5:-;8581:21;8612:24;8661:12;:19;;;:26;8691:1;8661:31;8653:57;;;;;;;37370:2:31;8653:57:5;;;37352:21:31;37409:2;37389:18;;;37382:30;37448:15;37428:18;;;37421:43;37481:18;;8653:57:5;37168:337:31;8653:57:5;8729:19;;;;8768:16;;;8782:1;8768:16;;;;;;;;;8729:19;;-1:-1:-1;8768:16:5;;;;;;;;;;;;-1:-1:-1;8768:16:5;8758:26;;8807:6;8794:7;8802:1;8794:10;;;;;;;;:::i;:::-;;;;;;:19;;;;;;;;;;;8450:370;;;;;:::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;;;;;;;37901:2:31;8113:60:0;;;37883:21:31;37940:2;37920:18;;;37913:30;37979:31;37959:18;;;37952:59;38028:18;;8113:60:0;37699: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:171::-;894:20;;954:18;943:30;;933:41;;923:69;;988:1;985;978:12;923:69;827:171;;;:::o;1003:184::-;1055:77;1052:1;1045:88;1152:4;1149:1;1142:15;1176:4;1173:1;1166:15;1192:253;1264:2;1258:9;1306:4;1294:17;;1341:18;1326:34;;1362:22;;;1323:62;1320:88;;;1388:18;;:::i;:::-;1424:2;1417:22;1192:253;:::o;1450:257::-;1522:4;1516:11;;;1554:17;;1601:18;1586:34;;1622:22;;;1583:62;1580:88;;;1648:18;;:::i;1712:334::-;1783:2;1777:9;1839:2;1829:13;;1844:66;1825:86;1813:99;;1942:18;1927:34;;1963:22;;;1924:62;1921:88;;;1989:18;;:::i;:::-;2025:2;2018:22;1712:334;;-1:-1:-1;1712:334:31:o;2051:186::-;2114:4;2147:18;2139:6;2136:30;2133:56;;;2169:18;;:::i;:::-;-1:-1:-1;2214:1:31;2210:14;2226:4;2206:25;;2051:186::o;2242:156::-;2308:20;;2368:4;2357:16;;2347:27;;2337:55;;2388:1;2385;2378:12;2403:1055;2460:5;2513:3;2506:4;2498:6;2494:17;2490:27;2480:55;;2531:1;2528;2521:12;2480:55;2567:6;2554:20;2593:4;2617:63;2633:46;2676:2;2633:46;:::i;:::-;2617:63;:::i;:::-;2714:15;;;2776:4;2819:13;;;2807:26;;2803:35;;;2745:12;;;;2702:3;2850:15;;;2847:35;;;2878:1;2875;2868:12;2847:35;2914:2;2906:6;2902:15;2926:503;2942:6;2937:3;2934:15;2926:503;;;3018:2;3012:3;3007;3003:13;2999:22;2996:112;;;3062:1;3091:2;3087;3080:14;2996:112;3134:22;;:::i;:::-;3183:21;3200:3;3183:21;:::i;:::-;3169:36;;3254:12;;;3241:26;3225:14;;;3218:50;3291:2;3342:12;;;3329:26;3313:14;;;3306:50;3369:18;;3407:12;;;;2959;;2926:503;;3463:893;3616:6;3624;3632;3676:9;3667:7;3663:23;3706:3;3702:2;3698:12;3695:32;;;3723:1;3720;3713:12;3695:32;3746:28;3764:9;3746:28;:::i;:::-;3736:38;;3867:4;3798:66;3794:2;3790:75;3786:86;3783:106;;;3885:1;3882;3875:12;3783:106;;3911:22;;:::i;:::-;3985:2;3974:9;3970:18;3957:32;3998:33;4023:7;3998:33;:::i;:::-;4040:22;;4122:4;4107:20;;4094:34;4089:2;4078:14;;4071:58;4047:5;-1:-1:-1;4204:2:31;4189:18;;4176:32;4231:18;4220:30;;4217:50;;;4263:1;4260;4253:12;4217:50;4286:64;4342:7;4333:6;4322:9;4318:22;4286:64;:::i;:::-;4276:74;;;3463:893;;;;;:::o;4361:681::-;4532:2;4584:21;;;4654:13;;4557:18;;;4676:22;;;4503:4;;4532:2;4755:15;;;;4729:2;4714:18;;;4503:4;4798:218;4812:6;4809:1;4806:13;4798:218;;;4877:13;;4892:42;4873:62;4861:75;;4991:15;;;;4956:12;;;;4834:1;4827:9;4798:218;;5047:180;5106:6;5159:2;5147:9;5138:7;5134:23;5130:32;5127:52;;;5175:1;5172;5165:12;5127:52;-1:-1:-1;5198:23:31;;5047:180;-1:-1:-1;5047:180:31:o;6022:163::-;6089:20;;6149:10;6138:22;;6128:33;;6118:61;;6175:1;6172;6165:12;6190:415;6276:6;6329:2;6317:9;6308:7;6304:23;6300:32;6297:52;;;6345:1;6342;6335:12;6297:52;6371:22;;:::i;:::-;6429:9;6416:23;6409:5;6402:38;6500:2;6489:9;6485:18;6472:32;6467:2;6460:5;6456:14;6449:56;6537:37;6570:2;6559:9;6555:18;6537:37;:::i;:::-;6532:2;6521:14;;6514:61;6525:5;6190:415;-1:-1:-1;;;6190:415:31:o;6921:279::-;6698:12;;6712:10;6694:29;6682:42;;6777:4;6766:16;;;6760:23;6785:42;6756:72;6740:14;;;6733:96;6882:4;6871:16;;;6865:23;6890:18;6861:48;6845:14;;;6838:72;7127:2;7112:18;;7139:55;6610:306;7397:1044;7455:5;7503:4;7491:9;7486:3;7482:19;7478:30;7475:50;;;7521:1;7518;7511:12;7475:50;7543:22;;:::i;:::-;7534:31;;7602:9;7589:23;7621:33;7646:7;7621:33;:::i;:::-;7663:22;;7704:2;7742:18;;;7729:32;7784:18;7773:30;;7770:50;;;7816:1;7813;7806:12;7770:50;7839:22;;7892:4;7884:13;;7880:23;-1:-1:-1;7870:51:31;;7917:1;7914;7907:12;7870:51;7953:2;7940:16;7976:63;7992:46;8035:2;7992:46;:::i;7976:63::-;8073:15;;;8155:1;8151:10;;;;8143:19;;8139:28;;;8104:12;;;;8179:15;;;8176:35;;;8207:1;8204;8197:12;8176:35;8231:11;;;;8251:146;8267:6;8262:3;8259:15;8251:146;;;8333:21;8350:3;8333:21;:::i;:::-;8321:34;;8284:12;;;;8375;;;;8251:146;;;8429:5;8424:2;8417:5;8413:14;8406:29;;;;;;7397:1044;;;;:::o;8446:488::-;8543:6;8551;8604:2;8592:9;8583:7;8579:23;8575:32;8572:52;;;8620:1;8617;8610:12;8572:52;8659:9;8646:23;8678:31;8703:5;8678:31;:::i;:::-;8728:5;-1:-1:-1;8784:2:31;8769:18;;8756:32;8811:18;8800:30;;8797:50;;;8843:1;8840;8833:12;8797:50;8866:62;8920:7;8911:6;8900:9;8896:22;8866:62;:::i;:::-;8856:72;;;8446:488;;;;;:::o;9325:353::-;9413:6;9466:2;9454:9;9445:7;9441:23;9437:32;9434:52;;;9482:1;9479;9472:12;9434:52;9522:9;9509:23;9555:18;9547:6;9544:30;9541:50;;;9587:1;9584;9577:12;9541:50;9610:62;9664:7;9655:6;9644:9;9640:22;9610:62;:::i;9683:188::-;9751:20;;9811:34;9800:46;;9790:57;;9780:85;;9861:1;9858;9851:12;9876:661;9971:6;10024:3;10012:9;10003:7;9999:23;9995:33;9992:53;;;10041:1;10038;10031:12;9992:53;10074:2;10068:9;10116:3;10108:6;10104:16;10186:6;10174:10;10171:22;10150:18;10138:10;10135:34;10132:62;10129:88;;;10197:18;;:::i;:::-;10237:10;10233:2;10226:22;;10285:9;10272:23;10264:6;10257:39;10357:2;10346:9;10342:18;10329:32;10324:2;10316:6;10312:15;10305:57;10395:38;10429:2;10418:9;10414:18;10395:38;:::i;:::-;10390:2;10382:6;10378:15;10371:63;10467:38;10501:2;10490:9;10486:18;10467:38;:::i;:::-;10462:2;10450:15;;10443:63;10454:6;9876:661;-1:-1:-1;;;9876:661:31:o;10542:794::-;10630:6;10638;10646;10654;10707:2;10695:9;10686:7;10682:23;10678:32;10675:52;;;10723:1;10720;10713:12;10675:52;10762:9;10749:23;10781:31;10806:5;10781:31;:::i;:::-;10831:5;-1:-1:-1;10883:2:31;10868:18;;10855:32;;-1:-1:-1;10938:2:31;10923:18;;10910:32;10961:18;10991:14;;;10988:34;;;11018:1;11015;11008:12;10988:34;11056:6;11045:9;11041:22;11031:32;;11101:7;11094:4;11090:2;11086:13;11082:27;11072:55;;11123:1;11120;11113:12;11072:55;11163:2;11150:16;11189:2;11181:6;11178:14;11175:34;;;11205:1;11202;11195:12;11175:34;11250:7;11245:2;11236:6;11232:2;11228:15;11224:24;11221:37;11218:57;;;11271:1;11268;11261:12;11218:57;10542:794;;;;-1:-1:-1;;11302:2:31;11294:11;;-1:-1:-1;;;10542:794:31:o;11341:250::-;11426:1;11436:113;11450:6;11447:1;11444:13;11436:113;;;11526:11;;;11520:18;11507:11;;;11500:39;11472:2;11465:10;11436:113;;;-1:-1:-1;;11583:1:31;11565:16;;11558:27;11341:250::o;11596:329::-;11637:3;11675:5;11669:12;11702:6;11697:3;11690:19;11718:76;11787:6;11780:4;11775:3;11771:14;11764:4;11757:5;11753:16;11718:76;:::i;:::-;11839:2;11827:15;11844:66;11823:88;11814:98;;;;11914:4;11810:109;;11596:329;-1:-1:-1;;11596:329:31:o;11930:298::-;12113:6;12106:14;12099:22;12088:9;12081:41;12158:2;12153;12142:9;12138:18;12131:30;12062:4;12178:44;12218:2;12207:9;12203:18;12195:6;12178:44;:::i;12233:632::-;12404:2;12456:21;;;12526:13;;12429:18;;;12548:22;;;12375:4;;12404:2;12627:15;;;;12601:2;12586:18;;;12375:4;12670:169;12684:6;12681:1;12678:13;12670:169;;;12745:13;;12733:26;;12814:15;;;;12779:12;;;;12706:1;12699:9;12670:169;;13686:248;13754:6;13762;13815:2;13803:9;13794:7;13790:23;13786:32;13783:52;;;13831:1;13828;13821:12;13783:52;-1:-1:-1;;13854:23:31;;;13924:2;13909:18;;;13896:32;;-1:-1:-1;13686:248:31:o;13939:626::-;14036:6;14044;14097:2;14085:9;14076:7;14072:23;14068:32;14065:52;;;14113:1;14110;14103:12;14065:52;14153:9;14140:23;14182:18;14223:2;14215:6;14212:14;14209:34;;;14239:1;14236;14229:12;14209:34;14277:6;14266:9;14262:22;14252:32;;14322:7;14315:4;14311:2;14307:13;14303:27;14293:55;;14344:1;14341;14334:12;14293:55;14384:2;14371:16;14410:2;14402:6;14399:14;14396:34;;;14426:1;14423;14416:12;14396:34;14479:7;14474:2;14464:6;14461:1;14457:14;14453:2;14449:23;14445:32;14442:45;14439:65;;;14500:1;14497;14490:12;14439:65;14531:2;14523:11;;;;;14553:6;;-1:-1:-1;13939:626:31;;-1:-1:-1;;;;13939:626:31:o;14570:859::-;14730:4;14759:2;14799;14788:9;14784:18;14829:2;14818:9;14811:21;14852:6;14887;14881:13;14918:6;14910;14903:22;14956:2;14945:9;14941:18;14934:25;;15018:2;15008:6;15005:1;15001:14;14990:9;14986:30;14982:39;14968:53;;15056:2;15048:6;15044:15;15077:1;15087:313;15101:6;15098:1;15095:13;15087:313;;;15190:66;15178:9;15170:6;15166:22;15162:95;15157:3;15150:108;15281:39;15313:6;15304;15298:13;15281:39;:::i;:::-;15271:49;-1:-1:-1;15378:12:31;;;;15343:15;;;;15123:1;15116:9;15087:313;;;-1:-1:-1;15417:6:31;;14570:859;-1:-1:-1;;;;;;;14570:859:31:o;15434:502::-;15529:6;15582:2;15570:9;15561:7;15557:23;15553:32;15550:52;;;15598:1;15595;15588:12;15550:52;15624:22;;:::i;:::-;15669:28;15687:9;15669:28;:::i;:::-;15662:5;15655:43;15750:2;15739:9;15735:18;15722:32;15763:33;15788:7;15763:33;:::i;:::-;15823:2;15812:14;;15805:31;15868:37;15901:2;15886:18;;15868:37;:::i;15941:857::-;16120:2;16131:21;;;16233:13;;16248:42;16229:62;16209:18;;;16202:90;16327:15;;;16321:22;16381:4;16359:20;;;16352:34;16435:19;;16190:2;16175:18;;16463:22;;;16091:4;;16120:2;16543:21;;;16091:4;;16516:3;16501:19;;;16592:180;16606:6;16603:1;16600:13;16592:180;;;16671:13;;16686:4;16667:24;16655:37;;16747:15;;;;16628:1;16621:9;;;;;16712:12;;;;16592:180;;;-1:-1:-1;16789:3:31;15941:857;-1:-1:-1;;;;;;15941:857:31:o;16803:969::-;16887:6;16918:2;16961;16949:9;16940:7;16936:23;16932:32;16929:52;;;16977:1;16974;16967:12;16929:52;17017:9;17004:23;17050:18;17042:6;17039:30;17036:50;;;17082:1;17079;17072:12;17036:50;17105:22;;17158:4;17150:13;;17146:27;-1:-1:-1;17136:55:31;;17187:1;17184;17177:12;17136:55;17223:2;17210:16;17246:63;17262:46;17305:2;17262:46;:::i;17246:63::-;17343:15;;;17425:1;17421:10;;;;17413:19;;17409:28;;;17374:12;;;;17449:19;;;17446:39;;;17481:1;17478;17471:12;17446:39;17505:11;;;;17525:217;17541:6;17536:3;17533:15;17525:217;;;17621:3;17608:17;17638:31;17663:5;17638:31;:::i;:::-;17682:18;;17558:12;;;;17720;;;;17525:217;;;17761:5;16803:969;-1:-1:-1;;;;;;;16803:969:31:o;17777:512::-;17899:6;17907;17915;17968:2;17956:9;17947:7;17943:23;17939:32;17936:52;;;17984:1;17981;17974:12;17936:52;18007:28;18025:9;18007:28;:::i;:::-;17997:38;;18082:2;18071:9;18067:18;18054:32;18044:42;;18137:2;18126:9;18122:18;18109:32;18164:18;18156:6;18153:30;18150:50;;;18196:1;18193;18186:12;18294:301;18382:1;18375:5;18372:12;18362:200;;18418:77;18415:1;18408:88;18519:4;18516:1;18509:15;18547:4;18544:1;18537:15;18362:200;18571:18;;18294:301::o;18600:648::-;6698:12;;6712:10;6694:29;6682:42;;6777:4;6766:16;;;6760:23;6785:42;6756:72;6740:14;;;6733:96;6882:4;6871:16;;;6865:23;6890:18;6861:48;6845:14;;;6838:72;18943:3;18928:19;;19020:60;19076:2;19065:9;19061:18;19053:6;19020:60;:::i;:::-;19136:42;19127:6;19121:13;19117:62;19111:3;19100:9;19096:19;19089:91;19235:4;19227:6;19223:17;19217:24;19211:3;19200:9;19196:19;19189:53;18600:648;;;;;;:::o;19253:184::-;19305:77;19302:1;19295:88;19402:4;19399:1;19392:15;19426:4;19423:1;19416:15;22489:271;22672:6;22664;22659:3;22646:33;22628:3;22698:16;;22723:13;;;22698:16;22489:271;-1:-1:-1;22489:271:31:o;23450:274::-;23543:6;23596:2;23584:9;23575:7;23571:23;23567:32;23564:52;;;23612:1;23609;23602:12;23564:52;23644:9;23638:16;23663:31;23688:5;23663:31;:::i;23729:885::-;23838:6;23891:3;23879:9;23870:7;23866:23;23862:33;23859:53;;;23908:1;23905;23898:12;23859:53;23941:2;23935:9;23983:3;23975:6;23971:16;24053:6;24041:10;24038:22;24017:18;24005:10;24002:34;23999:62;23996:88;;;24064:18;;:::i;:::-;24104:10;24100:2;24093:22;;24145:9;24139:16;24131:6;24124:32;24210:2;24199:9;24195:18;24189:25;24184:2;24176:6;24172:15;24165:50;24269:2;24258:9;24254:18;24248:25;24243:2;24235:6;24231:15;24224:50;24328:2;24317:9;24313:18;24307:25;24302:2;24294:6;24290:15;24283:50;24388:3;24377:9;24373:19;24367:26;24361:3;24353:6;24349:16;24342:52;24449:3;24438:9;24434:19;24428:26;24422:3;24414:6;24410:16;24403:52;24498:3;24487:9;24483:19;24477:26;24512:31;24537:5;24512:31;:::i;:::-;24571:3;24559:16;;24552:31;24563:6;23729:885;-1:-1:-1;;;23729:885:31:o;25008:184::-;25060:77;25057:1;25050:88;25157:4;25154:1;25147:15;25181:4;25178:1;25171:15;25197:128;25264:9;;;25285:11;;;25282:37;;;25299:18;;:::i;26010:580::-;26087:4;26093:6;26153:11;26140:25;26243:66;26232:8;26216:14;26212:29;26208:102;26188:18;26184:127;26174:155;;26325:1;26322;26315:12;26174:155;26352:33;;26404:20;;;-1:-1:-1;26447:18:31;26436:30;;26433:50;;;26479:1;26476;26469:12;26433:50;26512:4;26500:17;;-1:-1:-1;26543:14:31;26539:27;;;26529:38;;26526:58;;;26580:1;26577;26570:12;26595:440;26824:6;26816;26811:3;26798:33;26780:3;26859:6;26854:3;26850:16;26886:1;26882:2;26875:13;26917:6;26911:13;26933:65;26991:6;26987:2;26980:4;26972:6;26968:17;26933:65;:::i;:::-;27014:15;;26595:440;-1:-1:-1;;;;;26595:440:31:o;28068:125::-;28133:9;;;28154:10;;;28151:36;;;28167:18;;:::i;29219:468::-;6698:12;;6712:10;6694:29;6682:42;;6777:4;6766:16;;;6760:23;6785:42;6756:72;6740:14;;;6733:96;6882:4;6871:16;;;6865:23;6890:18;6861:48;6845:14;;;6838:72;29500:3;29485:19;;29577:60;29633:2;29622:9;29618:18;29610:6;29577:60;:::i;:::-;29674:6;29668:3;29657:9;29653:19;29646:35;29219:468;;;;;;:::o;31087:184::-;31157:6;31210:2;31198:9;31189:7;31185:23;31181:32;31178:52;;;31226:1;31223;31216:12;31178:52;-1:-1:-1;31249:16:31;;31087:184;-1:-1:-1;31087:184:31:o;32243:197::-;32311:34;32365:10;;;32377;;;32361:27;;32400:11;;;32397:37;;;32414:18;;:::i;32806:200::-;32875:34;32942:10;;;32930;;;32926:27;;32965:12;;;32962:38;;;32980:18;;:::i;35992:209::-;36030:3;36058:18;36111:2;36104:5;36100:14;36138:2;36129:7;36126:15;36123:41;;36144:18;;:::i;:::-;36193:1;36180:15;;35992:209;-1:-1:-1;;;35992:209:31:o;36876:287::-;37005:3;37043:6;37037:13;37059:66;37118:6;37113:3;37106:4;37098:6;37094:17;37059:66;:::i;:::-;37141:16;;;;;36876:287;-1:-1:-1;;36876:287:31:o;37510:184::-;37562:77;37559:1;37552:88;37659:4;37656:1;37649:15;37683:4;37680:1;37673:15;38057:219;38206:2;38195:9;38188:21;38169:4;38226:44;38266:2;38255:9;38251:18;38243:6;38226:44;:::i
Swarm Source
ipfs://dae8ce0fdf8a19b8ef61f228069ce65a82d9928b390af40043f3f60f60e9a4b6
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.