- Contract name:
- PeggedTokenBridgeV2
- Optimization enabled
- true
- Compiler version
- v0.8.9+commit.e5eed63a
- Optimization runs
- 800
- Verified at
- 2022-12-01T07:21:32.183647Z
Constructor Arguments
000000000000000000000000841ce48f9446c8e281d3f1444cb859b4a6d0738c
Arg [0] (address) : 0x841ce48f9446c8e281d3f1444cb859b4a6d0738c
Contract source code
// Sources flattened with hardhat v2.9.0 https://hardhat.org // File contracts/interfaces/ISigsVerifier.sol // SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.9; interface ISigsVerifier { /** * @notice Verifies that a message is signed by a quorum among the signers. * @param _msg signed message * @param _sigs list of signatures sorted by signer addresses in ascending order * @param _signers sorted list of current signers * @param _powers powers of current signers */ function verifySigs( bytes memory _msg, bytes[] calldata _sigs, address[] calldata _signers, uint256[] calldata _powers ) external view; } // File contracts/interfaces/IPeggedToken.sol interface IPeggedToken { function mint(address _to, uint256 _amount) external; function burn(address _from, uint256 _amount) external; } // File contracts/interfaces/IPeggedTokenBurnFrom.sol // used for pegged token with openzeppelin ERC20Burnable interface // only compatible with PeggedTokenBridgeV2 interface IPeggedTokenBurnFrom { function mint(address _to, uint256 _amount) external; function burnFrom(address _from, uint256 _amount) external; } // File contracts/libraries/Pb.sol // runtime proto sol library library Pb { enum WireType { Varint, Fixed64, LengthDelim, StartGroup, EndGroup, Fixed32 } struct Buffer { uint256 idx; // the start index of next read. when idx=b.length, we're done bytes b; // hold serialized proto msg, readonly } // create a new in-memory Buffer object from raw msg bytes function fromBytes(bytes memory raw) internal pure returns (Buffer memory buf) { buf.b = raw; buf.idx = 0; } // whether there are unread bytes function hasMore(Buffer memory buf) internal pure returns (bool) { return buf.idx < buf.b.length; } // decode current field number and wiretype function decKey(Buffer memory buf) internal pure returns (uint256 tag, WireType wiretype) { uint256 v = decVarint(buf); tag = v / 8; wiretype = WireType(v & 7); } // count tag occurrences, return an array due to no memory map support // have to create array for (maxtag+1) size. cnts[tag] = occurrences // should keep buf.idx unchanged because this is only a count function function cntTags(Buffer memory buf, uint256 maxtag) internal pure returns (uint256[] memory cnts) { uint256 originalIdx = buf.idx; cnts = new uint256[](maxtag + 1); // protobuf's tags are from 1 rather than 0 uint256 tag; WireType wire; while (hasMore(buf)) { (tag, wire) = decKey(buf); cnts[tag] += 1; skipValue(buf, wire); } buf.idx = originalIdx; } // read varint from current buf idx, move buf.idx to next read, return the int value function decVarint(Buffer memory buf) internal pure returns (uint256 v) { bytes10 tmp; // proto int is at most 10 bytes (7 bits can be used per byte) bytes memory bb = buf.b; // get buf.b mem addr to use in assembly v = buf.idx; // use v to save one additional uint variable assembly { tmp := mload(add(add(bb, 32), v)) // load 10 bytes from buf.b[buf.idx] to tmp } uint256 b; // store current byte content v = 0; // reset to 0 for return value for (uint256 i = 0; i < 10; i++) { assembly { b := byte(i, tmp) // don't use tmp[i] because it does bound check and costs extra } v |= (b & 0x7F) << (i * 7); if (b & 0x80 == 0) { buf.idx += i + 1; return v; } } revert(); // i=10, invalid varint stream } // read length delimited field and return bytes function decBytes(Buffer memory buf) internal pure returns (bytes memory b) { uint256 len = decVarint(buf); uint256 end = buf.idx + len; require(end <= buf.b.length); // avoid overflow b = new bytes(len); bytes memory bufB = buf.b; // get buf.b mem addr to use in assembly uint256 bStart; uint256 bufBStart = buf.idx; assembly { bStart := add(b, 32) bufBStart := add(add(bufB, 32), bufBStart) } for (uint256 i = 0; i < len; i += 32) { assembly { mstore(add(bStart, i), mload(add(bufBStart, i))) } } buf.idx = end; } // return packed ints function decPacked(Buffer memory buf) internal pure returns (uint256[] memory t) { uint256 len = decVarint(buf); uint256 end = buf.idx + len; require(end <= buf.b.length); // avoid overflow // array in memory must be init w/ known length // so we have to create a tmp array w/ max possible len first uint256[] memory tmp = new uint256[](len); uint256 i = 0; // count how many ints are there while (buf.idx < end) { tmp[i] = decVarint(buf); i++; } t = new uint256[](i); // init t with correct length for (uint256 j = 0; j < i; j++) { t[j] = tmp[j]; } return t; } // move idx pass current value field, to beginning of next tag or msg end function skipValue(Buffer memory buf, WireType wire) internal pure { if (wire == WireType.Varint) { decVarint(buf); } else if (wire == WireType.LengthDelim) { uint256 len = decVarint(buf); buf.idx += len; // skip len bytes value data require(buf.idx <= buf.b.length); // avoid overflow } else { revert(); } // unsupported wiretype } // type conversion help utils function _bool(uint256 x) internal pure returns (bool v) { return x != 0; } function _uint256(bytes memory b) internal pure returns (uint256 v) { require(b.length <= 32); // b's length must be smaller than or equal to 32 assembly { v := mload(add(b, 32)) } // load all 32bytes to v v = v >> (8 * (32 - b.length)); // only first b.length is valid } function _address(bytes memory b) internal pure returns (address v) { v = _addressPayable(b); } function _addressPayable(bytes memory b) internal pure returns (address payable v) { require(b.length == 20); //load 32bytes then shift right 12 bytes assembly { v := div(mload(add(b, 32)), 0x1000000000000000000000000) } } function _bytes32(bytes memory b) internal pure returns (bytes32 v) { require(b.length == 32); assembly { v := mload(add(b, 32)) } } // uint[] to uint8[] function uint8s(uint256[] memory arr) internal pure returns (uint8[] memory t) { t = new uint8[](arr.length); for (uint256 i = 0; i < t.length; i++) { t[i] = uint8(arr[i]); } } function uint32s(uint256[] memory arr) internal pure returns (uint32[] memory t) { t = new uint32[](arr.length); for (uint256 i = 0; i < t.length; i++) { t[i] = uint32(arr[i]); } } function uint64s(uint256[] memory arr) internal pure returns (uint64[] memory t) { t = new uint64[](arr.length); for (uint256 i = 0; i < t.length; i++) { t[i] = uint64(arr[i]); } } function bools(uint256[] memory arr) internal pure returns (bool[] memory t) { t = new bool[](arr.length); for (uint256 i = 0; i < t.length; i++) { t[i] = arr[i] != 0; } } } // File contracts/libraries/PbPegged.sol // Code generated by protoc-gen-sol. DO NOT EDIT. // source: contracts/libraries/proto/pegged.proto library PbPegged { using Pb for Pb.Buffer; // so we can call Pb funcs on Buffer obj struct Mint { address token; // tag: 1 address account; // tag: 2 uint256 amount; // tag: 3 address depositor; // tag: 4 uint64 refChainId; // tag: 5 bytes32 refId; // tag: 6 } // end struct Mint function decMint(bytes memory raw) internal pure returns (Mint memory m) { Pb.Buffer memory buf = Pb.fromBytes(raw); uint256 tag; Pb.WireType wire; while (buf.hasMore()) { (tag, wire) = buf.decKey(); if (false) {} // solidity has no switch/case else if (tag == 1) { m.token = Pb._address(buf.decBytes()); } else if (tag == 2) { m.account = Pb._address(buf.decBytes()); } else if (tag == 3) { m.amount = Pb._uint256(buf.decBytes()); } else if (tag == 4) { m.depositor = Pb._address(buf.decBytes()); } else if (tag == 5) { m.refChainId = uint64(buf.decVarint()); } else if (tag == 6) { m.refId = Pb._bytes32(buf.decBytes()); } else { buf.skipValue(wire); } // skip value of unknown tag } } // end decoder Mint struct Withdraw { address token; // tag: 1 address receiver; // tag: 2 uint256 amount; // tag: 3 address burnAccount; // tag: 4 uint64 refChainId; // tag: 5 bytes32 refId; // tag: 6 } // end struct Withdraw function decWithdraw(bytes memory raw) internal pure returns (Withdraw memory m) { Pb.Buffer memory buf = Pb.fromBytes(raw); uint256 tag; Pb.WireType wire; while (buf.hasMore()) { (tag, wire) = buf.decKey(); if (false) {} // solidity has no switch/case else if (tag == 1) { m.token = Pb._address(buf.decBytes()); } else if (tag == 2) { m.receiver = Pb._address(buf.decBytes()); } else if (tag == 3) { m.amount = Pb._uint256(buf.decBytes()); } else if (tag == 4) { m.burnAccount = Pb._address(buf.decBytes()); } else if (tag == 5) { m.refChainId = uint64(buf.decVarint()); } else if (tag == 6) { m.refId = Pb._bytes32(buf.decBytes()); } else { buf.skipValue(wire); } // skip value of unknown tag } } // end decoder Withdraw } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.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 Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts v4.4.1 (access/Ownable.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 Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/security/[email protected] // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File contracts/safeguard/Pauser.sol abstract contract Pauser is Ownable, Pausable { mapping(address => bool) public pausers; event PauserAdded(address account); event PauserRemoved(address account); constructor() { _addPauser(msg.sender); } modifier onlyPauser() { require(isPauser(msg.sender), "Caller is not pauser"); _; } function pause() public onlyPauser { _pause(); } function unpause() public onlyPauser { _unpause(); } function isPauser(address account) public view returns (bool) { return pausers[account]; } function addPauser(address account) public onlyOwner { _addPauser(account); } function removePauser(address account) public onlyOwner { _removePauser(account); } function renouncePauser() public { _removePauser(msg.sender); } function _addPauser(address account) private { require(!isPauser(account), "Account is already pauser"); pausers[account] = true; emit PauserAdded(account); } function _removePauser(address account) private { require(isPauser(account), "Account is not pauser"); pausers[account] = false; emit PauserRemoved(account); } } // File contracts/safeguard/Governor.sol abstract contract Governor is Ownable { mapping(address => bool) public governors; event GovernorAdded(address account); event GovernorRemoved(address account); modifier onlyGovernor() { require(isGovernor(msg.sender), "Caller is not governor"); _; } constructor() { _addGovernor(msg.sender); } function isGovernor(address _account) public view returns (bool) { return governors[_account]; } function addGovernor(address _account) public onlyOwner { _addGovernor(_account); } function removeGovernor(address _account) public onlyOwner { _removeGovernor(_account); } function renounceGovernor() public { _removeGovernor(msg.sender); } function _addGovernor(address _account) private { require(!isGovernor(_account), "Account is already governor"); governors[_account] = true; emit GovernorAdded(_account); } function _removeGovernor(address _account) private { require(isGovernor(_account), "Account is not governor"); governors[_account] = false; emit GovernorRemoved(_account); } } // File contracts/safeguard/VolumeControl.sol abstract contract VolumeControl is Governor { uint256 public epochLength; // seconds mapping(address => uint256) public epochVolumes; // key is token mapping(address => uint256) public epochVolumeCaps; // key is token mapping(address => uint256) public lastOpTimestamps; // key is token event EpochLengthUpdated(uint256 length); event EpochVolumeUpdated(address token, uint256 cap); function setEpochLength(uint256 _length) external onlyGovernor { epochLength = _length; emit EpochLengthUpdated(_length); } function setEpochVolumeCaps(address[] calldata _tokens, uint256[] calldata _caps) external onlyGovernor { require(_tokens.length == _caps.length, "length mismatch"); for (uint256 i = 0; i < _tokens.length; i++) { epochVolumeCaps[_tokens[i]] = _caps[i]; emit EpochVolumeUpdated(_tokens[i], _caps[i]); } } function _updateVolume(address _token, uint256 _amount) internal { if (epochLength == 0) { return; } uint256 cap = epochVolumeCaps[_token]; if (cap == 0) { return; } uint256 volume = epochVolumes[_token]; uint256 timestamp = block.timestamp; uint256 epochStartTime = (timestamp / epochLength) * epochLength; if (lastOpTimestamps[_token] < epochStartTime) { volume = _amount; } else { volume += _amount; } require(volume <= cap, "volume exceeds cap"); epochVolumes[_token] = volume; lastOpTimestamps[_token] = timestamp; } } // File contracts/safeguard/DelayedTransfer.sol abstract contract DelayedTransfer is Governor { struct delayedTransfer { address receiver; address token; uint256 amount; uint256 timestamp; } mapping(bytes32 => delayedTransfer) public delayedTransfers; mapping(address => uint256) public delayThresholds; uint256 public delayPeriod; // in seconds event DelayedTransferAdded(bytes32 id); event DelayedTransferExecuted(bytes32 id, address receiver, address token, uint256 amount); event DelayPeriodUpdated(uint256 period); event DelayThresholdUpdated(address token, uint256 threshold); function setDelayThresholds(address[] calldata _tokens, uint256[] calldata _thresholds) external onlyGovernor { require(_tokens.length == _thresholds.length, "length mismatch"); for (uint256 i = 0; i < _tokens.length; i++) { delayThresholds[_tokens[i]] = _thresholds[i]; emit DelayThresholdUpdated(_tokens[i], _thresholds[i]); } } function setDelayPeriod(uint256 _period) external onlyGovernor { delayPeriod = _period; emit DelayPeriodUpdated(_period); } function _addDelayedTransfer( bytes32 id, address receiver, address token, uint256 amount ) internal { require(delayedTransfers[id].timestamp == 0, "delayed transfer already exists"); delayedTransfers[id] = delayedTransfer({ receiver: receiver, token: token, amount: amount, timestamp: block.timestamp }); emit DelayedTransferAdded(id); } // caller needs to do the actual token transfer function _executeDelayedTransfer(bytes32 id) internal returns (delayedTransfer memory) { delayedTransfer memory transfer = delayedTransfers[id]; require(transfer.timestamp > 0, "delayed transfer not exist"); require(block.timestamp > transfer.timestamp + delayPeriod, "delayed transfer still locked"); delete delayedTransfers[id]; emit DelayedTransferExecuted(id, transfer.receiver, transfer.token, transfer.amount); return transfer; } } // File contracts/pegged-bridge/PeggedTokenBridgeV2.sol /** * @title The bridge contract to mint and burn pegged tokens * @dev Work together with OriginalTokenVault deployed at remote chains. */ contract PeggedTokenBridgeV2 is Pauser, VolumeControl, DelayedTransfer { ISigsVerifier public immutable sigsVerifier; mapping(bytes32 => bool) public records; mapping(address => uint256) public minBurn; mapping(address => uint256) public maxBurn; event Mint( bytes32 mintId, address token, address account, uint256 amount, // ref_chain_id defines the reference chain ID, taking values of: // 1. The common case: the chain ID on which the remote corresponding deposit or burn happened; // 2. Refund for wrong burn: this chain ID on which the burn happened uint64 refChainId, // ref_id defines a unique reference ID, taking values of: // 1. The common case of deposit/burn-mint: the deposit or burn ID on the remote chain; // 2. Refund for wrong burn: the burn ID on this chain bytes32 refId, address depositor ); event Burn( bytes32 burnId, address token, address account, uint256 amount, uint64 toChainId, address toAccount, uint64 nonce ); event MinBurnUpdated(address token, uint256 amount); event MaxBurnUpdated(address token, uint256 amount); constructor(ISigsVerifier _sigsVerifier) { sigsVerifier = _sigsVerifier; } /** * @notice Mint tokens triggered by deposit at a remote chain's OriginalTokenVault. * @param _request The serialized Mint protobuf. * @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by * +2/3 of the sigsVerifier's current signing power to be delivered. * @param _signers The sorted list of signers. * @param _powers The signing powers of the signers. */ function mint( bytes calldata _request, bytes[] calldata _sigs, address[] calldata _signers, uint256[] calldata _powers ) external whenNotPaused returns (bytes32) { bytes32 domain = keccak256(abi.encodePacked(block.chainid, address(this), "Mint")); sigsVerifier.verifySigs(abi.encodePacked(domain, _request), _sigs, _signers, _powers); PbPegged.Mint memory request = PbPegged.decMint(_request); bytes32 mintId = keccak256( // len = 20 + 20 + 32 + 20 + 8 + 32 + 20 = 152 abi.encodePacked( request.account, request.token, request.amount, request.depositor, request.refChainId, request.refId, address(this) ) ); require(records[mintId] == false, "record exists"); records[mintId] = true; _updateVolume(request.token, request.amount); uint256 delayThreshold = delayThresholds[request.token]; if (delayThreshold > 0 && request.amount > delayThreshold) { _addDelayedTransfer(mintId, request.account, request.token, request.amount); } else { IPeggedToken(request.token).mint(request.account, request.amount); } emit Mint( mintId, request.token, request.account, request.amount, request.refChainId, request.refId, request.depositor ); return mintId; } /** * @notice Burn pegged tokens to trigger a cross-chain withdrawal of the original tokens at a remote chain's * OriginalTokenVault, or mint at another remote chain * NOTE: This function DOES NOT SUPPORT fee-on-transfer / rebasing tokens. * @param _token The pegged token address. * @param _amount The amount to burn. * @param _toChainId If zero, withdraw from original vault; otherwise, the remote chain to mint tokens. * @param _toAccount The account to receive tokens on the remote chain * @param _nonce A number to guarantee unique depositId. Can be timestamp in practice. */ function burn( address _token, uint256 _amount, uint64 _toChainId, address _toAccount, uint64 _nonce ) external whenNotPaused returns (bytes32) { bytes32 burnId = _burn(_token, _amount, _toChainId, _toAccount, _nonce); IPeggedToken(_token).burn(msg.sender, _amount); return burnId; } // same with `burn` above, use openzeppelin ERC20Burnable interface function burnFrom( address _token, uint256 _amount, uint64 _toChainId, address _toAccount, uint64 _nonce ) external whenNotPaused returns (bytes32) { bytes32 burnId = _burn(_token, _amount, _toChainId, _toAccount, _nonce); IPeggedTokenBurnFrom(_token).burnFrom(msg.sender, _amount); return burnId; } function _burn( address _token, uint256 _amount, uint64 _toChainId, address _toAccount, uint64 _nonce ) private returns (bytes32) { require(_amount > minBurn[_token], "amount too small"); require(maxBurn[_token] == 0 || _amount <= maxBurn[_token], "amount too large"); bytes32 burnId = keccak256( // len = 20 + 20 + 32 + 8 + 20 + 8 + 8 + 20 = 136 abi.encodePacked( msg.sender, _token, _amount, _toChainId, _toAccount, _nonce, uint64(block.chainid), address(this) ) ); require(records[burnId] == false, "record exists"); records[burnId] = true; emit Burn(burnId, _token, msg.sender, _amount, _toChainId, _toAccount, _nonce); return burnId; } function executeDelayedTransfer(bytes32 id) external whenNotPaused { delayedTransfer memory transfer = _executeDelayedTransfer(id); IPeggedToken(transfer.token).mint(transfer.receiver, transfer.amount); } function setMinBurn(address[] calldata _tokens, uint256[] calldata _amounts) external onlyGovernor { require(_tokens.length == _amounts.length, "length mismatch"); for (uint256 i = 0; i < _tokens.length; i++) { minBurn[_tokens[i]] = _amounts[i]; emit MinBurnUpdated(_tokens[i], _amounts[i]); } } function setMaxBurn(address[] calldata _tokens, uint256[] calldata _amounts) external onlyGovernor { require(_tokens.length == _amounts.length, "length mismatch"); for (uint256 i = 0; i < _tokens.length; i++) { maxBurn[_tokens[i]] = _amounts[i]; emit MaxBurnUpdated(_tokens[i], _amounts[i]); } } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_sigsVerifier","internalType":"contract ISigsVerifier"}]},{"type":"event","name":"Burn","inputs":[{"type":"bytes32","name":"burnId","internalType":"bytes32","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"address","name":"account","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint64","name":"toChainId","internalType":"uint64","indexed":false},{"type":"address","name":"toAccount","internalType":"address","indexed":false},{"type":"uint64","name":"nonce","internalType":"uint64","indexed":false}],"anonymous":false},{"type":"event","name":"DelayPeriodUpdated","inputs":[{"type":"uint256","name":"period","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DelayThresholdUpdated","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"threshold","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DelayedTransferAdded","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"DelayedTransferExecuted","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":false},{"type":"address","name":"receiver","internalType":"address","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"EpochLengthUpdated","inputs":[{"type":"uint256","name":"length","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"EpochVolumeUpdated","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"cap","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"GovernorAdded","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernorRemoved","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"MaxBurnUpdated","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"MinBurnUpdated","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Mint","inputs":[{"type":"bytes32","name":"mintId","internalType":"bytes32","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"address","name":"account","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint64","name":"refChainId","internalType":"uint64","indexed":false},{"type":"bytes32","name":"refId","internalType":"bytes32","indexed":false},{"type":"address","name":"depositor","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"PauserAdded","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"PauserRemoved","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addGovernor","inputs":[{"type":"address","name":"_account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addPauser","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"burn","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint64","name":"_toChainId","internalType":"uint64"},{"type":"address","name":"_toAccount","internalType":"address"},{"type":"uint64","name":"_nonce","internalType":"uint64"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"burnFrom","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint64","name":"_toChainId","internalType":"uint64"},{"type":"address","name":"_toAccount","internalType":"address"},{"type":"uint64","name":"_nonce","internalType":"uint64"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"delayPeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"delayThresholds","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"receiver","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}],"name":"delayedTransfers","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"epochLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"epochVolumeCaps","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"epochVolumes","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeDelayedTransfer","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"governors","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isGovernor","inputs":[{"type":"address","name":"_account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPauser","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastOpTimestamps","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxBurn","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minBurn","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"mint","inputs":[{"type":"bytes","name":"_request","internalType":"bytes"},{"type":"bytes[]","name":"_sigs","internalType":"bytes[]"},{"type":"address[]","name":"_signers","internalType":"address[]"},{"type":"uint256[]","name":"_powers","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"pausers","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"records","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeGovernor","inputs":[{"type":"address","name":"_account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removePauser","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceGovernor","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renouncePauser","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDelayPeriod","inputs":[{"type":"uint256","name":"_period","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDelayThresholds","inputs":[{"type":"address[]","name":"_tokens","internalType":"address[]"},{"type":"uint256[]","name":"_thresholds","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setEpochLength","inputs":[{"type":"uint256","name":"_length","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setEpochVolumeCaps","inputs":[{"type":"address[]","name":"_tokens","internalType":"address[]"},{"type":"uint256[]","name":"_caps","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxBurn","inputs":[{"type":"address[]","name":"_tokens","internalType":"address[]"},{"type":"uint256[]","name":"_amounts","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinBurn","inputs":[{"type":"address[]","name":"_tokens","internalType":"address[]"},{"type":"uint256[]","name":"_amounts","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ISigsVerifier"}],"name":"sigsVerifier","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]}]
Contract Creation Code
0x60a06040523480156200001157600080fd5b5060405162002ec538038062002ec583398101604081905262000034916200024f565b6200003f3362000074565b6000805460ff60a01b191690556200005733620000c4565b62000062336200018f565b6001600160a01b031660805262000281565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811660009081526001602052604090205460ff1615620001335760405162461bcd60e51b815260206004820152601960248201527f4163636f756e7420697320616c7265616479207061757365720000000000000060448201526064015b60405180910390fd5b6001600160a01b038116600081815260016020818152604092839020805460ff191690921790915590519182527f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f891015b60405180910390a150565b6001600160a01b03811660009081526002602052604090205460ff1615620001fa5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c726561647920676f7665726e6f72000000000060448201526064016200012a565b6001600160a01b038116600081815260026020908152604091829020805460ff1916600117905590519182527fdc5a48d79e2e147530ff63ecdbed5a5a66adb9d5cf339384d5d076da197c40b5910162000184565b6000602082840312156200026257600080fd5b81516001600160a01b03811681146200027a57600080fd5b9392505050565b608051612c21620002a46000396000818161055f01526112bb0152612c216000f3fe608060405234801561001057600080fd5b50600436106102775760003560e01c806382dc1ec411610160578063bf4816f0116100d8578063eecdac881161008c578063f832138311610071578063f8321383146105fe578063f87343021461061e578063f9a8ea081461063157600080fd5b8063eecdac88146105d8578063f2fde38b146105eb57600080fd5b8063e026049c116100bd578063e026049c14610581578063e3eece2614610589578063e43581b8146105ac57600080fd5b8063bf4816f014610547578063ccf2683b1461055a57600080fd5b80639e422c331161012f578063adc0d57f11610114578063adc0d57f146104b1578063b1c94d941461051e578063b5f2bc471461052757600080fd5b80639e422c331461048b578063a00293011461049e57600080fd5b806382dc1ec4146104385780638456cb591461044b5780638da5cb5b146104535780639e25fc5c1461047857600080fd5b806354eea796116101f35780636b2c0f55116101c2578063715018a6116101a7578063715018a6146103ed5780637f856013146103f557806380f51c121461041557600080fd5b80636b2c0f55146103d25780636ef8d66d146103e557600080fd5b806354eea7961461038457806357d775f8146103975780635c975abb146103a057806360216b00146103b257600080fd5b80633f4ba83a1161024a57806347b16c6c1161022f57806347b16c6c14610323578063497bf3b21461033657806352532faa1461036457600080fd5b80633f4ba83a146102ef57806346fbf68e146102f757600080fd5b806301e647251461027c57806317bdbae5146102b45780633c4a25d0146102c95780633d572107146102dc575b600080fd5b61029f61028a366004612691565b600a6020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6102c76102c23660046126f6565b610644565b005b6102c76102d736600461277e565b6107e7565b6102c76102ea366004612691565b61084d565b6102c76108e1565b61029f61030536600461277e565b6001600160a01b031660009081526001602052604090205460ff1690565b6102c76103313660046126f6565b61094a565b61035661034436600461277e565b600c6020526000908152604090205481565b6040519081526020016102ab565b61035661037236600461277e565b60086020526000908152604090205481565b6102c7610392366004612691565b610ae1565b61035660035481565b600054600160a01b900460ff1661029f565b6103566103c036600461277e565b60046020526000908152604090205481565b6102c76103e036600461277e565b610b6e565b6102c7610bd1565b6102c7610bda565b61035661040336600461277e565b600b6020526000908152604090205481565b61029f61042336600461277e565b60016020526000908152604090205460ff1681565b6102c761044636600461277e565b610c3e565b6102c7610ca1565b6000546001600160a01b03165b6040516001600160a01b0390911681526020016102ab565b6102c7610486366004612691565b610d08565b6103566104993660046127b8565b610dd5565b6103566104ac3660046127b8565b610ea1565b6104f36104bf366004612691565b60076020526000908152604090208054600182015460028301546003909301546001600160a01b0392831693919092169184565b604080516001600160a01b0395861681529490931660208501529183015260608201526080016102ab565b61035660095481565b61035661053536600461277e565b60056020526000908152604090205481565b6102c76105553660046126f6565b610f34565b6104607f000000000000000000000000000000000000000000000000000000000000000081565b6102c76110cb565b61029f61059736600461277e565b60026020526000908152604090205460ff1681565b61029f6105ba36600461277e565b6001600160a01b031660009081526002602052604090205460ff1690565b6102c76105e636600461277e565b6110d4565b6102c76105f936600461277e565b611137565b61035661060c36600461277e565b60066020526000908152604090205481565b61035661062c366004612816565b611216565b6102c761063f3660046126f6565b61162b565b3360009081526002602052604090205460ff166106a15760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b60448201526064015b60405180910390fd5b8281146106e25760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606401610698565b60005b838110156107e0578282828181106106ff576106ff612905565b905060200201356008600087878581811061071c5761071c612905565b9050602002016020810190610731919061277e565b6001600160a01b031681526020810191909152604001600020557fceaad6533bfb481492fb3e08ef19297f46611b8fa9de5ef4cf8dc23a56ad09ce85858381811061077e5761077e612905565b9050602002016020810190610793919061277e565b8484848181106107a5576107a5612905565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a1806107d881612931565b9150506106e5565b5050505050565b6000546001600160a01b031633146108415760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61084a816117c2565b50565b3360009081526002602052604090205460ff166108a55760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b60098190556040518181527fc0a39f234199b125fb93713c4d067bdcebbf691087f87b79c0feb92b156ba8b6906020015b60405180910390a150565b3360009081526001602052604090205460ff166109405760405162461bcd60e51b815260206004820152601460248201527f43616c6c6572206973206e6f74207061757365720000000000000000000000006044820152606401610698565b61094861187f565b565b3360009081526002602052604090205460ff166109a25760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b8281146109e35760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606401610698565b60005b838110156107e057828282818110610a0057610a00612905565b9050602002013560056000878785818110610a1d57610a1d612905565b9050602002016020810190610a32919061277e565b6001600160a01b031681526020810191909152604001600020557f608e49c22994f20b5d3496dca088b88dfd81b4a3e8cc3809ea1e10a320107e89858583818110610a7f57610a7f612905565b9050602002016020810190610a94919061277e565b848484818110610aa657610aa6612905565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a180610ad981612931565b9150506109e6565b3360009081526002602052604090205460ff16610b395760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b60038190556040518181527f2664fec2ff76486ac58ed087310855b648b15b9d19f3de8529e95f7c46b7d6b3906020016108d6565b6000546001600160a01b03163314610bc85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61084a81611925565b61094833611925565b6000546001600160a01b03163314610c345760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61094860006119de565b6000546001600160a01b03163314610c985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61084a81611a3b565b3360009081526001602052604090205460ff16610d005760405162461bcd60e51b815260206004820152601460248201527f43616c6c6572206973206e6f74207061757365720000000000000000000000006044820152606401610698565b610948611af9565b600054600160a01b900460ff1615610d555760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b6000610d6082611b81565b6020810151815160408084015190516340c10f1960e01b81526001600160a01b039283166004820152602481019190915292935016906340c10f1990604401600060405180830381600087803b158015610db957600080fd5b505af1158015610dcd573d6000803e3d6000fd5b505050505050565b60008054600160a01b900460ff1615610e235760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b6000610e328787878787611d53565b60405163079cc67960e41b8152336004820152602481018890529091506001600160a01b038816906379cc6790906044015b600060405180830381600087803b158015610e7e57600080fd5b505af1158015610e92573d6000803e3d6000fd5b50929998505050505050505050565b60008054600160a01b900460ff1615610eef5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b6000610efe8787878787611d53565b604051632770a7eb60e21b8152336004820152602481018890529091506001600160a01b03881690639dc29fac90604401610e64565b3360009081526002602052604090205460ff16610f8c5760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b828114610fcd5760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606401610698565b60005b838110156107e057828282818110610fea57610fea612905565b90506020020135600b600087878581811061100757611007612905565b905060200201602081019061101c919061277e565b6001600160a01b031681526020810191909152604001600020557f3796cd0b17a8734f8da819920625598e9a18be490f686725282e5383f1d0668385858381811061106957611069612905565b905060200201602081019061107e919061277e565b84848481811061109057611090612905565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a1806110c381612931565b915050610fd0565b61094833611fc6565b6000546001600160a01b0316331461112e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61084a81611fc6565b6000546001600160a01b031633146111915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b6001600160a01b03811661120d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610698565b61084a816119de565b60008054600160a01b900460ff16156112645760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b600046306040516020016112a192919091825260601b6bffffffffffffffffffffffff1916602082015263135a5b9d60e21b603482015260380190565b6040516020818303038152906040528051906020012090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663682dbc22828c8c6040516020016112fd9392919061294c565b6040516020818303038152906040528a8a8a8a8a8a6040518863ffffffff1660e01b81526004016113349796959493929190612ab3565b60006040518083038186803b15801561134c57600080fd5b505afa158015611360573d6000803e3d6000fd5b5050505060006113a58b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061207f92505050565b6020818101518251604080850151606080870151608088015160a089015185516bffffffffffffffffffffffff1998851b8916818b015296841b88166034880152604887019490945290821b8616606886015277ffffffffffffffffffffffffffffffffffffffffffffffff1960c09190911b16607c850152608484019190915230901b90921660a48201528151808203609801815260b890910182528051908301206000818152600a9093529120549192509060ff16156114995760405162461bcd60e51b815260206004820152600d60248201526c7265636f72642065786973747360981b6044820152606401610698565b6000818152600a602052604090819020805460ff191660011790558251908301516114c491906121e1565b81516001600160a01b031660009081526008602052604090205480158015906114f05750808360400151115b156115125761150d828460200151856000015186604001516122f9565b611582565b8251602084015160408086015190516340c10f1960e01b81526001600160a01b03928316600482015260248101919091529116906340c10f1990604401600060405180830381600087803b15801561156957600080fd5b505af115801561157d573d6000803e3d6000fd5b505050505b7f5bc84ecccfced5bb04bfc7f3efcdbe7f5cd21949ef146811b4d1967fe41f777a8284600001518560200151866040015187608001518860a00151896060015160405161161397969594939291909687526001600160a01b0395861660208801529385166040870152606086019290925267ffffffffffffffff16608085015260a08401521660c082015260e00190565b60405180910390a1509b9a5050505050505050505050565b3360009081526002602052604090205460ff166116835760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b8281146116c45760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606401610698565b60005b838110156107e0578282828181106116e1576116e1612905565b90506020020135600c60008787858181106116fe576116fe612905565b9050602002016020810190611713919061277e565b6001600160a01b031681526020810191909152604001600020557fa3181379f6db47d9037efc6b6e8e3efe8c55ddb090b4f0512c152f97c4e47da585858381811061176057611760612905565b9050602002016020810190611775919061277e565b84848481811061178757611787612905565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a1806117ba81612931565b9150506116c7565b6001600160a01b03811660009081526002602052604090205460ff161561182b5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c726561647920676f7665726e6f7200000000006044820152606401610698565b6001600160a01b038116600081815260026020908152604091829020805460ff1916600117905590519182527fdc5a48d79e2e147530ff63ecdbed5a5a66adb9d5cf339384d5d076da197c40b591016108d6565b600054600160a01b900460ff166118d85760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610698565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b03811660009081526001602052604090205460ff1661198d5760405162461bcd60e51b815260206004820152601560248201527f4163636f756e74206973206e6f742070617573657200000000000000000000006044820152606401610698565b6001600160a01b038116600081815260016020908152604091829020805460ff1916905590519182527fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e91016108d6565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811660009081526001602052604090205460ff1615611aa45760405162461bcd60e51b815260206004820152601960248201527f4163636f756e7420697320616c726561647920706175736572000000000000006044820152606401610698565b6001600160a01b038116600081815260016020818152604092839020805460ff191690921790915590519182527f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f891016108d6565b600054600160a01b900460ff1615611b465760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586119083390565b604080516080810182526000808252602082018190529181018290526060810191909152600082815260076020908152604091829020825160808101845281546001600160a01b0390811682526001830154169281019290925260028101549282019290925260039091015460608201819052611c405760405162461bcd60e51b815260206004820152601a60248201527f64656c61796564207472616e73666572206e6f742065786973740000000000006044820152606401610698565b6009548160600151611c529190612b4f565b4211611ca05760405162461bcd60e51b815260206004820152601d60248201527f64656c61796564207472616e73666572207374696c6c206c6f636b65640000006044820152606401610698565b6000838152600760209081526040808320805473ffffffffffffffffffffffffffffffffffffffff199081168255600182018054909116905560028101849055600301929092558251908301518383015192517f3b40e5089937425d14cdd96947e5661868357e224af59bd8b24a4b8a330d442693611d4593889390929091909384526001600160a01b03928316602085015291166040830152606082015260800190565b60405180910390a192915050565b6001600160a01b0385166000908152600b60205260408120548511611dba5760405162461bcd60e51b815260206004820152601060248201527f616d6f756e7420746f6f20736d616c6c000000000000000000000000000000006044820152606401610698565b6001600160a01b0386166000908152600c60205260409020541580611df757506001600160a01b0386166000908152600c60205260409020548511155b611e435760405162461bcd60e51b815260206004820152601060248201527f616d6f756e7420746f6f206c61726765000000000000000000000000000000006044820152606401610698565b6040516bffffffffffffffffffffffff1933606090811b8216602084015288811b821660348401526048830188905277ffffffffffffffffffffffffffffffffffffffffffffffff1960c088811b8216606886015287831b8416607086015286811b8216608486015246901b16608c84015230901b16609482015260009060a80160408051601f1981840301815291815281516020928301206000818152600a90935291205490915060ff1615611f2c5760405162461bcd60e51b815260206004820152600d60248201526c7265636f72642065786973747360981b6044820152606401610698565b6000818152600a6020908152604091829020805460ff1916600117905581518381526001600160a01b038a81169282019290925233928101929092526060820188905267ffffffffffffffff878116608084015290861660a0830152841660c08201527f6298d7b58f235730b3b399dc5c282f15dae8b022e5fbbf89cee21fd83c8810a39060e00160405180910390a19695505050505050565b6001600160a01b03811660009081526002602052604090205460ff1661202e5760405162461bcd60e51b815260206004820152601760248201527f4163636f756e74206973206e6f7420676f7665726e6f720000000000000000006044820152606401610698565b6001600160a01b038116600081815260026020908152604091829020805460ff1916905590519182527f1ebe834e73d60a5fec822c1e1727d34bc79f2ad977ed504581cc1822fe20fb5b91016108d6565b6040805160c08101825260008082526020808301829052828401829052606083018290526080830182905260a0830182905283518085019094528184528301849052909190805b602083015151835110156121d9576120dd83612419565b9092509050816001141561210c576120fc6120f784612453565b612510565b6001600160a01b031684526120c6565b8160021415612134576121216120f784612453565b6001600160a01b031660208501526120c6565b81600314156121585761214e61214984612453565b612521565b60408501526120c6565b81600414156121805761216d6120f784612453565b6001600160a01b031660608501526120c6565b81600514156121a65761219283612558565b67ffffffffffffffff1660808501526120c6565b81600614156121ca576121c06121bb84612453565b6125da565b60a08501526120c6565b6121d483826125f2565b6120c6565b505050919050565b6003546121ec575050565b6001600160a01b0382166000908152600560205260409020548061220f57505050565b6001600160a01b038316600090815260046020526040812054600354909142916122398184612b67565b6122439190612b89565b6001600160a01b03871660009081526006602052604090205490915081111561226e5784925061227b565b6122788584612b4f565b92505b838311156122cb5760405162461bcd60e51b815260206004820152601260248201527f766f6c756d6520657863656564732063617000000000000000000000000000006044820152606401610698565b506001600160a01b039094166000908152600460209081526040808320939093556006905220929092555050565b600084815260076020526040902060030154156123585760405162461bcd60e51b815260206004820152601f60248201527f64656c61796564207472616e7366657220616c726561647920657869737473006044820152606401610698565b604080516080810182526001600160a01b0380861682528481166020808401918252838501868152426060860190815260008b81526007909352918690209451855490851673ffffffffffffffffffffffffffffffffffffffff1991821617865592516001860180549190951693169290921790925551600283015551600390910155517fcbcfffe5102114216a85d3aceb14ad4b81a3935b1b5c468fadf3889eb9c5dce69061240b9086815260200190565b60405180910390a150505050565b600080600061242784612558565b9050612434600882612b67565b925080600716600581111561244b5761244b612ba8565b915050915091565b6060600061246083612558565b905060008184600001516124749190612b4f565b905083602001515181111561248857600080fd5b8167ffffffffffffffff8111156124a1576124a1612bbe565b6040519080825280601f01601f1916602001820160405280156124cb576020820181803683370190505b50602080860151865192955091818601919083010160005b858110156125055781810151838201526124fe602082612b4f565b90506124e3565b505050935250919050565b600061251b82612669565b92915050565b600060208251111561253257600080fd5b60208201519050815160206125479190612bd4565b612552906008612b89565b1c919050565b602080820151825181019091015160009182805b600a8110156125d45783811a9150612585816007612b89565b82607f16901b8517945081608016600014156125c2576125a6816001612b4f565b865187906125b5908390612b4f565b9052509395945050505050565b806125cc81612931565b91505061256c565b50600080fd5b600081516020146125ea57600080fd5b506020015190565b600081600581111561260657612606612ba8565b141561261a5761261582612558565b505050565b600281600581111561262e5761262e612ba8565b141561027757600061263f83612558565b905080836000018181516126539190612b4f565b9052506020830151518351111561261557600080fd5b6000815160141461267957600080fd5b50602001516c01000000000000000000000000900490565b6000602082840312156126a357600080fd5b5035919050565b60008083601f8401126126bc57600080fd5b50813567ffffffffffffffff8111156126d457600080fd5b6020830191508360208260051b85010111156126ef57600080fd5b9250929050565b6000806000806040858703121561270c57600080fd5b843567ffffffffffffffff8082111561272457600080fd5b612730888389016126aa565b9096509450602087013591508082111561274957600080fd5b50612756878288016126aa565b95989497509550505050565b80356001600160a01b038116811461277957600080fd5b919050565b60006020828403121561279057600080fd5b61279982612762565b9392505050565b803567ffffffffffffffff8116811461277957600080fd5b600080600080600060a086880312156127d057600080fd5b6127d986612762565b9450602086013593506127ee604087016127a0565b92506127fc60608701612762565b915061280a608087016127a0565b90509295509295909350565b6000806000806000806000806080898b03121561283257600080fd5b883567ffffffffffffffff8082111561284a57600080fd5b818b0191508b601f83011261285e57600080fd5b81358181111561286d57600080fd5b8c602082850101111561287f57600080fd5b60209283019a509850908a0135908082111561289a57600080fd5b6128a68c838d016126aa565b909850965060408b01359150808211156128bf57600080fd5b6128cb8c838d016126aa565b909650945060608b01359150808211156128e457600080fd5b506128f18b828c016126aa565b999c989b5096995094979396929594505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156129455761294561291b565b5060010190565b838152818360208301376000910160200190815292915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b818352600060208085019450848460051b86018460005b87811015612a105783830389528135601e198836030181126129c757600080fd5b8701803567ffffffffffffffff8111156129e057600080fd5b8036038913156129ef57600080fd5b6129fc8582898501612966565b9a87019a94505050908401906001016129a6565b5090979650505050505050565b8183526000602080850194508260005b85811015612a59576001600160a01b03612a4683612762565b1687529582019590820190600101612a2d565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612a9657600080fd5b8260051b8083602087013760009401602001938452509192915050565b608081526000885180608084015260005b81811015612ae1576020818c0181015160a0868401015201612ac4565b81811115612af357600060a083860101525b50601f01601f1916820182810360a09081016020850152612b17908201898b61298f565b90508281036040840152612b2c818789612a1d565b90508281036060840152612b41818587612a64565b9a9950505050505050505050565b60008219821115612b6257612b6261291b565b500190565b600082612b8457634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612ba357612ba361291b565b500290565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600082821015612be657612be661291b565b50039056fea2646970667358221220cf1de8e39feed918e8a2548fc8f45c9963a65d37beb2c51decc88e847298a7d164736f6c63430008090033000000000000000000000000841ce48f9446c8e281d3f1444cb859b4a6d0738c
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106102775760003560e01c806382dc1ec411610160578063bf4816f0116100d8578063eecdac881161008c578063f832138311610071578063f8321383146105fe578063f87343021461061e578063f9a8ea081461063157600080fd5b8063eecdac88146105d8578063f2fde38b146105eb57600080fd5b8063e026049c116100bd578063e026049c14610581578063e3eece2614610589578063e43581b8146105ac57600080fd5b8063bf4816f014610547578063ccf2683b1461055a57600080fd5b80639e422c331161012f578063adc0d57f11610114578063adc0d57f146104b1578063b1c94d941461051e578063b5f2bc471461052757600080fd5b80639e422c331461048b578063a00293011461049e57600080fd5b806382dc1ec4146104385780638456cb591461044b5780638da5cb5b146104535780639e25fc5c1461047857600080fd5b806354eea796116101f35780636b2c0f55116101c2578063715018a6116101a7578063715018a6146103ed5780637f856013146103f557806380f51c121461041557600080fd5b80636b2c0f55146103d25780636ef8d66d146103e557600080fd5b806354eea7961461038457806357d775f8146103975780635c975abb146103a057806360216b00146103b257600080fd5b80633f4ba83a1161024a57806347b16c6c1161022f57806347b16c6c14610323578063497bf3b21461033657806352532faa1461036457600080fd5b80633f4ba83a146102ef57806346fbf68e146102f757600080fd5b806301e647251461027c57806317bdbae5146102b45780633c4a25d0146102c95780633d572107146102dc575b600080fd5b61029f61028a366004612691565b600a6020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6102c76102c23660046126f6565b610644565b005b6102c76102d736600461277e565b6107e7565b6102c76102ea366004612691565b61084d565b6102c76108e1565b61029f61030536600461277e565b6001600160a01b031660009081526001602052604090205460ff1690565b6102c76103313660046126f6565b61094a565b61035661034436600461277e565b600c6020526000908152604090205481565b6040519081526020016102ab565b61035661037236600461277e565b60086020526000908152604090205481565b6102c7610392366004612691565b610ae1565b61035660035481565b600054600160a01b900460ff1661029f565b6103566103c036600461277e565b60046020526000908152604090205481565b6102c76103e036600461277e565b610b6e565b6102c7610bd1565b6102c7610bda565b61035661040336600461277e565b600b6020526000908152604090205481565b61029f61042336600461277e565b60016020526000908152604090205460ff1681565b6102c761044636600461277e565b610c3e565b6102c7610ca1565b6000546001600160a01b03165b6040516001600160a01b0390911681526020016102ab565b6102c7610486366004612691565b610d08565b6103566104993660046127b8565b610dd5565b6103566104ac3660046127b8565b610ea1565b6104f36104bf366004612691565b60076020526000908152604090208054600182015460028301546003909301546001600160a01b0392831693919092169184565b604080516001600160a01b0395861681529490931660208501529183015260608201526080016102ab565b61035660095481565b61035661053536600461277e565b60056020526000908152604090205481565b6102c76105553660046126f6565b610f34565b6104607f000000000000000000000000841ce48f9446c8e281d3f1444cb859b4a6d0738c81565b6102c76110cb565b61029f61059736600461277e565b60026020526000908152604090205460ff1681565b61029f6105ba36600461277e565b6001600160a01b031660009081526002602052604090205460ff1690565b6102c76105e636600461277e565b6110d4565b6102c76105f936600461277e565b611137565b61035661060c36600461277e565b60066020526000908152604090205481565b61035661062c366004612816565b611216565b6102c761063f3660046126f6565b61162b565b3360009081526002602052604090205460ff166106a15760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b60448201526064015b60405180910390fd5b8281146106e25760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606401610698565b60005b838110156107e0578282828181106106ff576106ff612905565b905060200201356008600087878581811061071c5761071c612905565b9050602002016020810190610731919061277e565b6001600160a01b031681526020810191909152604001600020557fceaad6533bfb481492fb3e08ef19297f46611b8fa9de5ef4cf8dc23a56ad09ce85858381811061077e5761077e612905565b9050602002016020810190610793919061277e565b8484848181106107a5576107a5612905565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a1806107d881612931565b9150506106e5565b5050505050565b6000546001600160a01b031633146108415760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61084a816117c2565b50565b3360009081526002602052604090205460ff166108a55760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b60098190556040518181527fc0a39f234199b125fb93713c4d067bdcebbf691087f87b79c0feb92b156ba8b6906020015b60405180910390a150565b3360009081526001602052604090205460ff166109405760405162461bcd60e51b815260206004820152601460248201527f43616c6c6572206973206e6f74207061757365720000000000000000000000006044820152606401610698565b61094861187f565b565b3360009081526002602052604090205460ff166109a25760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b8281146109e35760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606401610698565b60005b838110156107e057828282818110610a0057610a00612905565b9050602002013560056000878785818110610a1d57610a1d612905565b9050602002016020810190610a32919061277e565b6001600160a01b031681526020810191909152604001600020557f608e49c22994f20b5d3496dca088b88dfd81b4a3e8cc3809ea1e10a320107e89858583818110610a7f57610a7f612905565b9050602002016020810190610a94919061277e565b848484818110610aa657610aa6612905565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a180610ad981612931565b9150506109e6565b3360009081526002602052604090205460ff16610b395760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b60038190556040518181527f2664fec2ff76486ac58ed087310855b648b15b9d19f3de8529e95f7c46b7d6b3906020016108d6565b6000546001600160a01b03163314610bc85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61084a81611925565b61094833611925565b6000546001600160a01b03163314610c345760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61094860006119de565b6000546001600160a01b03163314610c985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61084a81611a3b565b3360009081526001602052604090205460ff16610d005760405162461bcd60e51b815260206004820152601460248201527f43616c6c6572206973206e6f74207061757365720000000000000000000000006044820152606401610698565b610948611af9565b600054600160a01b900460ff1615610d555760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b6000610d6082611b81565b6020810151815160408084015190516340c10f1960e01b81526001600160a01b039283166004820152602481019190915292935016906340c10f1990604401600060405180830381600087803b158015610db957600080fd5b505af1158015610dcd573d6000803e3d6000fd5b505050505050565b60008054600160a01b900460ff1615610e235760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b6000610e328787878787611d53565b60405163079cc67960e41b8152336004820152602481018890529091506001600160a01b038816906379cc6790906044015b600060405180830381600087803b158015610e7e57600080fd5b505af1158015610e92573d6000803e3d6000fd5b50929998505050505050505050565b60008054600160a01b900460ff1615610eef5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b6000610efe8787878787611d53565b604051632770a7eb60e21b8152336004820152602481018890529091506001600160a01b03881690639dc29fac90604401610e64565b3360009081526002602052604090205460ff16610f8c5760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b828114610fcd5760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606401610698565b60005b838110156107e057828282818110610fea57610fea612905565b90506020020135600b600087878581811061100757611007612905565b905060200201602081019061101c919061277e565b6001600160a01b031681526020810191909152604001600020557f3796cd0b17a8734f8da819920625598e9a18be490f686725282e5383f1d0668385858381811061106957611069612905565b905060200201602081019061107e919061277e565b84848481811061109057611090612905565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a1806110c381612931565b915050610fd0565b61094833611fc6565b6000546001600160a01b0316331461112e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b61084a81611fc6565b6000546001600160a01b031633146111915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610698565b6001600160a01b03811661120d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610698565b61084a816119de565b60008054600160a01b900460ff16156112645760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b600046306040516020016112a192919091825260601b6bffffffffffffffffffffffff1916602082015263135a5b9d60e21b603482015260380190565b6040516020818303038152906040528051906020012090507f000000000000000000000000841ce48f9446c8e281d3f1444cb859b4a6d0738c6001600160a01b031663682dbc22828c8c6040516020016112fd9392919061294c565b6040516020818303038152906040528a8a8a8a8a8a6040518863ffffffff1660e01b81526004016113349796959493929190612ab3565b60006040518083038186803b15801561134c57600080fd5b505afa158015611360573d6000803e3d6000fd5b5050505060006113a58b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061207f92505050565b6020818101518251604080850151606080870151608088015160a089015185516bffffffffffffffffffffffff1998851b8916818b015296841b88166034880152604887019490945290821b8616606886015277ffffffffffffffffffffffffffffffffffffffffffffffff1960c09190911b16607c850152608484019190915230901b90921660a48201528151808203609801815260b890910182528051908301206000818152600a9093529120549192509060ff16156114995760405162461bcd60e51b815260206004820152600d60248201526c7265636f72642065786973747360981b6044820152606401610698565b6000818152600a602052604090819020805460ff191660011790558251908301516114c491906121e1565b81516001600160a01b031660009081526008602052604090205480158015906114f05750808360400151115b156115125761150d828460200151856000015186604001516122f9565b611582565b8251602084015160408086015190516340c10f1960e01b81526001600160a01b03928316600482015260248101919091529116906340c10f1990604401600060405180830381600087803b15801561156957600080fd5b505af115801561157d573d6000803e3d6000fd5b505050505b7f5bc84ecccfced5bb04bfc7f3efcdbe7f5cd21949ef146811b4d1967fe41f777a8284600001518560200151866040015187608001518860a00151896060015160405161161397969594939291909687526001600160a01b0395861660208801529385166040870152606086019290925267ffffffffffffffff16608085015260a08401521660c082015260e00190565b60405180910390a1509b9a5050505050505050505050565b3360009081526002602052604090205460ff166116835760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba1033b7bb32b93737b960511b6044820152606401610698565b8281146116c45760405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606401610698565b60005b838110156107e0578282828181106116e1576116e1612905565b90506020020135600c60008787858181106116fe576116fe612905565b9050602002016020810190611713919061277e565b6001600160a01b031681526020810191909152604001600020557fa3181379f6db47d9037efc6b6e8e3efe8c55ddb090b4f0512c152f97c4e47da585858381811061176057611760612905565b9050602002016020810190611775919061277e565b84848481811061178757611787612905565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a1806117ba81612931565b9150506116c7565b6001600160a01b03811660009081526002602052604090205460ff161561182b5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c726561647920676f7665726e6f7200000000006044820152606401610698565b6001600160a01b038116600081815260026020908152604091829020805460ff1916600117905590519182527fdc5a48d79e2e147530ff63ecdbed5a5a66adb9d5cf339384d5d076da197c40b591016108d6565b600054600160a01b900460ff166118d85760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610698565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b03811660009081526001602052604090205460ff1661198d5760405162461bcd60e51b815260206004820152601560248201527f4163636f756e74206973206e6f742070617573657200000000000000000000006044820152606401610698565b6001600160a01b038116600081815260016020908152604091829020805460ff1916905590519182527fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e91016108d6565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811660009081526001602052604090205460ff1615611aa45760405162461bcd60e51b815260206004820152601960248201527f4163636f756e7420697320616c726561647920706175736572000000000000006044820152606401610698565b6001600160a01b038116600081815260016020818152604092839020805460ff191690921790915590519182527f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f891016108d6565b600054600160a01b900460ff1615611b465760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610698565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586119083390565b604080516080810182526000808252602082018190529181018290526060810191909152600082815260076020908152604091829020825160808101845281546001600160a01b0390811682526001830154169281019290925260028101549282019290925260039091015460608201819052611c405760405162461bcd60e51b815260206004820152601a60248201527f64656c61796564207472616e73666572206e6f742065786973740000000000006044820152606401610698565b6009548160600151611c529190612b4f565b4211611ca05760405162461bcd60e51b815260206004820152601d60248201527f64656c61796564207472616e73666572207374696c6c206c6f636b65640000006044820152606401610698565b6000838152600760209081526040808320805473ffffffffffffffffffffffffffffffffffffffff199081168255600182018054909116905560028101849055600301929092558251908301518383015192517f3b40e5089937425d14cdd96947e5661868357e224af59bd8b24a4b8a330d442693611d4593889390929091909384526001600160a01b03928316602085015291166040830152606082015260800190565b60405180910390a192915050565b6001600160a01b0385166000908152600b60205260408120548511611dba5760405162461bcd60e51b815260206004820152601060248201527f616d6f756e7420746f6f20736d616c6c000000000000000000000000000000006044820152606401610698565b6001600160a01b0386166000908152600c60205260409020541580611df757506001600160a01b0386166000908152600c60205260409020548511155b611e435760405162461bcd60e51b815260206004820152601060248201527f616d6f756e7420746f6f206c61726765000000000000000000000000000000006044820152606401610698565b6040516bffffffffffffffffffffffff1933606090811b8216602084015288811b821660348401526048830188905277ffffffffffffffffffffffffffffffffffffffffffffffff1960c088811b8216606886015287831b8416607086015286811b8216608486015246901b16608c84015230901b16609482015260009060a80160408051601f1981840301815291815281516020928301206000818152600a90935291205490915060ff1615611f2c5760405162461bcd60e51b815260206004820152600d60248201526c7265636f72642065786973747360981b6044820152606401610698565b6000818152600a6020908152604091829020805460ff1916600117905581518381526001600160a01b038a81169282019290925233928101929092526060820188905267ffffffffffffffff878116608084015290861660a0830152841660c08201527f6298d7b58f235730b3b399dc5c282f15dae8b022e5fbbf89cee21fd83c8810a39060e00160405180910390a19695505050505050565b6001600160a01b03811660009081526002602052604090205460ff1661202e5760405162461bcd60e51b815260206004820152601760248201527f4163636f756e74206973206e6f7420676f7665726e6f720000000000000000006044820152606401610698565b6001600160a01b038116600081815260026020908152604091829020805460ff1916905590519182527f1ebe834e73d60a5fec822c1e1727d34bc79f2ad977ed504581cc1822fe20fb5b91016108d6565b6040805160c08101825260008082526020808301829052828401829052606083018290526080830182905260a0830182905283518085019094528184528301849052909190805b602083015151835110156121d9576120dd83612419565b9092509050816001141561210c576120fc6120f784612453565b612510565b6001600160a01b031684526120c6565b8160021415612134576121216120f784612453565b6001600160a01b031660208501526120c6565b81600314156121585761214e61214984612453565b612521565b60408501526120c6565b81600414156121805761216d6120f784612453565b6001600160a01b031660608501526120c6565b81600514156121a65761219283612558565b67ffffffffffffffff1660808501526120c6565b81600614156121ca576121c06121bb84612453565b6125da565b60a08501526120c6565b6121d483826125f2565b6120c6565b505050919050565b6003546121ec575050565b6001600160a01b0382166000908152600560205260409020548061220f57505050565b6001600160a01b038316600090815260046020526040812054600354909142916122398184612b67565b6122439190612b89565b6001600160a01b03871660009081526006602052604090205490915081111561226e5784925061227b565b6122788584612b4f565b92505b838311156122cb5760405162461bcd60e51b815260206004820152601260248201527f766f6c756d6520657863656564732063617000000000000000000000000000006044820152606401610698565b506001600160a01b039094166000908152600460209081526040808320939093556006905220929092555050565b600084815260076020526040902060030154156123585760405162461bcd60e51b815260206004820152601f60248201527f64656c61796564207472616e7366657220616c726561647920657869737473006044820152606401610698565b604080516080810182526001600160a01b0380861682528481166020808401918252838501868152426060860190815260008b81526007909352918690209451855490851673ffffffffffffffffffffffffffffffffffffffff1991821617865592516001860180549190951693169290921790925551600283015551600390910155517fcbcfffe5102114216a85d3aceb14ad4b81a3935b1b5c468fadf3889eb9c5dce69061240b9086815260200190565b60405180910390a150505050565b600080600061242784612558565b9050612434600882612b67565b925080600716600581111561244b5761244b612ba8565b915050915091565b6060600061246083612558565b905060008184600001516124749190612b4f565b905083602001515181111561248857600080fd5b8167ffffffffffffffff8111156124a1576124a1612bbe565b6040519080825280601f01601f1916602001820160405280156124cb576020820181803683370190505b50602080860151865192955091818601919083010160005b858110156125055781810151838201526124fe602082612b4f565b90506124e3565b505050935250919050565b600061251b82612669565b92915050565b600060208251111561253257600080fd5b60208201519050815160206125479190612bd4565b612552906008612b89565b1c919050565b602080820151825181019091015160009182805b600a8110156125d45783811a9150612585816007612b89565b82607f16901b8517945081608016600014156125c2576125a6816001612b4f565b865187906125b5908390612b4f565b9052509395945050505050565b806125cc81612931565b91505061256c565b50600080fd5b600081516020146125ea57600080fd5b506020015190565b600081600581111561260657612606612ba8565b141561261a5761261582612558565b505050565b600281600581111561262e5761262e612ba8565b141561027757600061263f83612558565b905080836000018181516126539190612b4f565b9052506020830151518351111561261557600080fd5b6000815160141461267957600080fd5b50602001516c01000000000000000000000000900490565b6000602082840312156126a357600080fd5b5035919050565b60008083601f8401126126bc57600080fd5b50813567ffffffffffffffff8111156126d457600080fd5b6020830191508360208260051b85010111156126ef57600080fd5b9250929050565b6000806000806040858703121561270c57600080fd5b843567ffffffffffffffff8082111561272457600080fd5b612730888389016126aa565b9096509450602087013591508082111561274957600080fd5b50612756878288016126aa565b95989497509550505050565b80356001600160a01b038116811461277957600080fd5b919050565b60006020828403121561279057600080fd5b61279982612762565b9392505050565b803567ffffffffffffffff8116811461277957600080fd5b600080600080600060a086880312156127d057600080fd5b6127d986612762565b9450602086013593506127ee604087016127a0565b92506127fc60608701612762565b915061280a608087016127a0565b90509295509295909350565b6000806000806000806000806080898b03121561283257600080fd5b883567ffffffffffffffff8082111561284a57600080fd5b818b0191508b601f83011261285e57600080fd5b81358181111561286d57600080fd5b8c602082850101111561287f57600080fd5b60209283019a509850908a0135908082111561289a57600080fd5b6128a68c838d016126aa565b909850965060408b01359150808211156128bf57600080fd5b6128cb8c838d016126aa565b909650945060608b01359150808211156128e457600080fd5b506128f18b828c016126aa565b999c989b5096995094979396929594505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156129455761294561291b565b5060010190565b838152818360208301376000910160200190815292915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b818352600060208085019450848460051b86018460005b87811015612a105783830389528135601e198836030181126129c757600080fd5b8701803567ffffffffffffffff8111156129e057600080fd5b8036038913156129ef57600080fd5b6129fc8582898501612966565b9a87019a94505050908401906001016129a6565b5090979650505050505050565b8183526000602080850194508260005b85811015612a59576001600160a01b03612a4683612762565b1687529582019590820190600101612a2d565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612a9657600080fd5b8260051b8083602087013760009401602001938452509192915050565b608081526000885180608084015260005b81811015612ae1576020818c0181015160a0868401015201612ac4565b81811115612af357600060a083860101525b50601f01601f1916820182810360a09081016020850152612b17908201898b61298f565b90508281036040840152612b2c818789612a1d565b90508281036060840152612b41818587612a64565b9a9950505050505050505050565b60008219821115612b6257612b6261291b565b500190565b600082612b8457634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612ba357612ba361291b565b500290565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600082821015612be657612be661291b565b50039056fea2646970667358221220cf1de8e39feed918e8a2548fc8f45c9963a65d37beb2c51decc88e847298a7d164736f6c63430008090033