false
false

Contract Address Details

0x9acd3a79AaeB4301BAC0AE5d03ef45e76966132B

Creator
0x2ba7ed–54e3fc at 0xa651b6–245f44
Balance
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
11972177
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
OriginalTokenBridge




Optimization enabled
true
Compiler version
v0.8.17+commit.8df45f5f




Optimization runs
100000
EVM Version
default




Verified at
2023-12-10T11:57:57.000000Z

contracts/Bridge/OriginalTokenBridge.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";

contract OriginalTokenBridge is Initializable, ReentrancyGuardUpgradeable, AccessControlUpgradeable, UUPSUpgradeable {
    //============================ constants ============================//
    bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");
    bytes32 public constant ORIGINAL_BRIDGE_VALIDATOR = keccak256("ORIGINAL_BRIDGE_VALIDATOR_ALICE");
    bytes32 public constant SIDE_BRIDGE_VALIDATOR = keccak256("SIDE_BRIDGE_VALIDATOR_BOB");
    bytes32 public constant FINANCE_VALIDATOR = keccak256("FINANCE_VALIDATOR_CHARLIE");
    //============================ events ============================//
    event RequestMintWACEFromUserEvent(address indexed user, uint256 amount, uint256 nonce);
    event ResponseMintWACEFromValidator1Event(address indexed user, uint256 amount, uint256 nonce, uint32 returnCode);
    event RequestBurnWACEFromValidator2Event(address indexed user, uint256 amount, uint256 nonce);
    event ResponseBurnWACEFromValidator1Event(address indexed user, uint256 amount, uint256 nonce, uint32 returnCode);
    event WithdrawEvent(address indexed user, uint256 amount, uint256 nonce);
    //============================ error messages ============================//
    error NotEnoughFee();
    error InvalidNonce();
    error InvalidAmount();
    //============================ structs ============================//
    struct BridgeRequest {
        uint256 amount;
        uint256 nonce;
    }
    struct BridgeResponse {
        uint256 amount;
        uint256 nonce;
        uint32 returnCode;
    }
    //============================ storage ============================//
    uint256 private transitFee;
    mapping(address => BridgeRequest) private _requestMintWACEFromUser;
    mapping(address => BridgeResponse) private _responseMintWACEFromValidator1;
    mapping(address => BridgeRequest) private _requestBurnWACEFromValidator2;
    mapping(address => BridgeResponse) private _responseBurnWACEFromValidator1;
    mapping(address => uint256) private _S2OfinanceHandledNonce;
    uint256 public accumulatedUnwithdrawnFees;

    //============================ user functions ============================//
    function requestFromUser(uint256 nonce_, uint256 amount_) external payable {
        uint256 inputVal = msg.value;
        uint256 fee = _calculateFee(inputVal);
        uint256 amount = inputVal - fee;

        //check amount_ and nonce
        BridgeRequest memory latestRequest = _requestMintWACEFromUser[msg.sender];
        uint256 oldRequestNonce = latestRequest.nonce;
        if (nonce_ != (oldRequestNonce + 1)) {
            revert InvalidNonce();
        }
        //check response
        BridgeResponse memory latestResponse = _responseMintWACEFromValidator1[msg.sender];
        uint256 oldResponseNonce = latestResponse.nonce;
        if (nonce_ != (oldResponseNonce + 1)) {
            revert InvalidNonce(); //last request was not responsed, user request should be rejected
        }
        if (amount != amount_) {
            revert InvalidAmount();
        }

        //save to storage
        _requestMintWACEFromUser[msg.sender] = BridgeRequest(amount_, nonce_);

        accumulatedUnwithdrawnFees += fee;
        //emit event
        emit RequestMintWACEFromUserEvent(msg.sender, amount_, nonce_);
    }

    //============================ internal functions ============================//
    function _calculateFee(uint256 amount) internal view returns (uint256) {
        if (amount < transitFee) {
            revert NotEnoughFee();
        }
        return transitFee;
    }

    //============================ view functions ============================//
    function getRequestMintWACEFromUser(address who) external view returns (uint256, uint256) {
        BridgeRequest memory latestRequest = _requestMintWACEFromUser[who];
        return (latestRequest.nonce, latestRequest.amount);
    }

    function getResponseMintWACEFromValidator1(address who) external view returns (uint256, uint256, uint32) {
        BridgeResponse memory latestResponse = _responseMintWACEFromValidator1[who];
        return (latestResponse.nonce, latestResponse.amount, latestResponse.returnCode);
    }

    function getRequestBurnWACEFromValidator2(address who) external view returns (uint256, uint256) {
        BridgeRequest memory latestRequest = _requestBurnWACEFromValidator2[who];
        return (latestRequest.nonce, latestRequest.amount);
    }

    function getResponseBurnWACEFromValidator1(address who) external view returns (uint256, uint256, uint32) {
        BridgeResponse memory latestResponse = _responseBurnWACEFromValidator1[who];
        return (latestResponse.nonce, latestResponse.amount, latestResponse.returnCode);
    }

    function getS2OfinanceHandledNonce(address who) external view returns (uint256) {
        return _S2OfinanceHandledNonce[who];
    }

    function getTransitFee() external view returns (uint256) {
        return transitFee;
    }

    //============================ onlyOwner functions ============================//
    function requestBurnWACEFromValidator2(address who, uint256 nonce_, uint256 amount_) external onlyRole(SIDE_BRIDGE_VALIDATOR) {
        BridgeRequest memory latestRequest = _requestBurnWACEFromValidator2[who];
        uint256 oldRequestNonce = latestRequest.nonce;
        if (nonce_ != (oldRequestNonce + 1)) {
            revert InvalidNonce();
        }
        //check response
        BridgeResponse memory latestResponse = _responseBurnWACEFromValidator1[who];
        uint256 oldResponseNonce = latestResponse.nonce;
        if (nonce_ != (oldResponseNonce + 1)) {
            revert InvalidNonce();
        }
        //save to storage
        _requestBurnWACEFromValidator2[who] = BridgeRequest(amount_, nonce_);
        //emit event
        emit RequestBurnWACEFromValidator2Event(who, amount_, nonce_);
    }

    function responseBurnWACEFromValidator1(address who, uint256 nonce_, uint256 amount_, uint32 returnCode_) external onlyRole(ORIGINAL_BRIDGE_VALIDATOR) {
        BridgeRequest memory latestRequest = _requestBurnWACEFromValidator2[who];
        uint256 oldRequestNonce = latestRequest.nonce;
        if (nonce_ != oldRequestNonce) {
            revert InvalidNonce();
        }
        //check amount_
        if (latestRequest.amount != amount_) {
            revert InvalidAmount();
        }
        BridgeResponse memory latestResponse = _responseBurnWACEFromValidator1[who];
        uint256 oldResponseNonce = latestResponse.nonce;
        if (nonce_ != (oldResponseNonce + 1)) {
            revert InvalidNonce();
        }
        //save to storage
        _responseBurnWACEFromValidator1[who] = BridgeResponse(amount_, nonce_, returnCode_);
        //emit event
        emit ResponseBurnWACEFromValidator1Event(who, amount_, nonce_, returnCode_);
    }

    function withdraw(address payable to, uint256 nonce_, uint256 amount_) external nonReentrant onlyRole(FINANCE_VALIDATOR) {
        BridgeRequest memory latestRequest = _requestBurnWACEFromValidator2[to];
        uint256 oldRequestNonce = latestRequest.nonce;
        if (nonce_ != oldRequestNonce) {
            revert InvalidNonce();
        }
        BridgeResponse memory latestResponse = _responseBurnWACEFromValidator1[to];
        uint256 oldResponseNonce = latestResponse.nonce;
        if (nonce_ != oldResponseNonce) {
            revert InvalidNonce();
        }
        if (latestRequest.amount != amount_ && (latestResponse.amount != amount_)) {
            revert InvalidAmount();
        }
        if (nonce_ != (_S2OfinanceHandledNonce[to] + 1)) {
            revert InvalidNonce();
        }
        _S2OfinanceHandledNonce[to] = nonce_;
        (bool result, ) = to.call{value: amount_}("");
        require(result, "Transfer failed.");
        //emit event
        emit WithdrawEvent(to, amount_, nonce_);
    }

    function responseMintWACEFromValidator1(address who, uint256 nonce_, uint256 amount_, uint32 returnCode_) external onlyRole(ORIGINAL_BRIDGE_VALIDATOR) {
        //check amount_ and nonce_
        BridgeRequest memory latestRequest = _requestMintWACEFromUser[who];
        uint256 oldRequestNonce = latestRequest.nonce;
        if (nonce_ != oldRequestNonce) {
            revert InvalidNonce();
        }
        //check response
        BridgeResponse memory latestResponse = _responseMintWACEFromValidator1[who];
        uint256 oldResponseNonce = latestResponse.nonce;
        if (nonce_ != (oldResponseNonce + 1)) {
            revert InvalidNonce();
        }
        if (amount_ != latestRequest.amount) {
            revert InvalidAmount();
        }

        //save to storage
        _responseMintWACEFromValidator1[who] = BridgeResponse(amount_, nonce_, returnCode_);

        //emit event
        emit ResponseMintWACEFromValidator1Event(who, amount_, nonce_, returnCode_);
    }

    //dev: It's only used in really urgent situations, like if the bridge gets hacked. We use it to prevent any further losses.
    function forceWithdraw(uint256 amount_) external nonReentrant onlyRole(DEFAULT_ADMIN_ROLE) {
        address payable to = payable(msg.sender);
        (bool result, ) = to.call{value: amount_}("");
        require(result, "Transfer failed.");
    }

    function withdrawFee() external nonReentrant onlyRole(DEFAULT_ADMIN_ROLE) {
        address payable to = payable(msg.sender);
        uint256 amount = accumulatedUnwithdrawnFees;
        accumulatedUnwithdrawnFees = 0;
        (bool result, ) = to.call{value: amount}("");
        require(result, "Transfer failed.");
    }

    function setTransitFee(uint256 transitFee_) external onlyRole(FINANCE_VALIDATOR) {
        if (transitFee_ > 0 && transitFee_ < 100 ether) {
            transitFee = transitFee_;
        }
    }

    //========================================== Don't change anything below this line ============================================//
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initialize() public initializer {
        __AccessControl_init();
        __UUPSUpgradeable_init();

        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(UPGRADER_ROLE, msg.sender);

        __ReentrancyGuard_init();
        transitFee = 1 ether;
    }

    function _authorizeUpgrade(address newImplementation) internal override onlyRole(UPGRADER_ROLE) {}
}
        

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":100000,"enabled":true},"libraries":{}}
              

Contract ABI

[{"type":"constructor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DEFAULT_ADMIN_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"FINANCE_VALIDATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"ORIGINAL_BRIDGE_VALIDATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"SIDE_BRIDGE_VALIDATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"UPGRADER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"accumulatedUnwithdrawnFees","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"forceWithdraw","inputs":[{"type":"uint256","name":"amount_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRequestBurnWACEFromValidator2","inputs":[{"type":"address","name":"who","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRequestMintWACEFromUser","inputs":[{"type":"address","name":"who","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint32","name":"","internalType":"uint32"}],"name":"getResponseBurnWACEFromValidator1","inputs":[{"type":"address","name":"who","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint32","name":"","internalType":"uint32"}],"name":"getResponseMintWACEFromValidator1","inputs":[{"type":"address","name":"who","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoleAdmin","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getS2OfinanceHandledNonce","inputs":[{"type":"address","name":"who","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTransitFee","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"requestBurnWACEFromValidator2","inputs":[{"type":"address","name":"who","internalType":"address"},{"type":"uint256","name":"nonce_","internalType":"uint256"},{"type":"uint256","name":"amount_","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"requestFromUser","inputs":[{"type":"uint256","name":"nonce_","internalType":"uint256"},{"type":"uint256","name":"amount_","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"responseBurnWACEFromValidator1","inputs":[{"type":"address","name":"who","internalType":"address"},{"type":"uint256","name":"nonce_","internalType":"uint256"},{"type":"uint256","name":"amount_","internalType":"uint256"},{"type":"uint32","name":"returnCode_","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"responseMintWACEFromValidator1","inputs":[{"type":"address","name":"who","internalType":"address"},{"type":"uint256","name":"nonce_","internalType":"uint256"},{"type":"uint256","name":"amount_","internalType":"uint256"},{"type":"uint32","name":"returnCode_","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTransitFee","inputs":[{"type":"uint256","name":"transitFee_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"upgradeTo","inputs":[{"type":"address","name":"newImplementation","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"upgradeToAndCall","inputs":[{"type":"address","name":"newImplementation","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"to","internalType":"address payable"},{"type":"uint256","name":"nonce_","internalType":"uint256"},{"type":"uint256","name":"amount_","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawFee","inputs":[]},{"type":"event","name":"AdminChanged","inputs":[{"type":"address","name":"previousAdmin","indexed":false},{"type":"address","name":"newAdmin","indexed":false}],"anonymous":false},{"type":"event","name":"BeaconUpgraded","inputs":[{"type":"address","name":"beacon","indexed":true}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","indexed":false}],"anonymous":false},{"type":"event","name":"RequestBurnWACEFromValidator2Event","inputs":[{"type":"address","name":"user","indexed":true},{"type":"uint256","name":"amount","indexed":false},{"type":"uint256","name":"nonce","indexed":false}],"anonymous":false},{"type":"event","name":"RequestMintWACEFromUserEvent","inputs":[{"type":"address","name":"user","indexed":true},{"type":"uint256","name":"amount","indexed":false},{"type":"uint256","name":"nonce","indexed":false}],"anonymous":false},{"type":"event","name":"ResponseBurnWACEFromValidator1Event","inputs":[{"type":"address","name":"user","indexed":true},{"type":"uint256","name":"amount","indexed":false},{"type":"uint256","name":"nonce","indexed":false},{"type":"uint32","name":"returnCode","indexed":false}],"anonymous":false},{"type":"event","name":"ResponseMintWACEFromValidator1Event","inputs":[{"type":"address","name":"user","indexed":true},{"type":"uint256","name":"amount","indexed":false},{"type":"uint256","name":"nonce","indexed":false},{"type":"uint32","name":"returnCode","indexed":false}],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"bytes32","name":"previousAdminRole","indexed":true},{"type":"bytes32","name":"newAdminRole","indexed":true}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"address","name":"account","indexed":true},{"type":"address","name":"sender","indexed":true}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"address","name":"account","indexed":true},{"type":"address","name":"sender","indexed":true}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"implementation","indexed":true}],"anonymous":false},{"type":"event","name":"WithdrawEvent","inputs":[{"type":"address","name":"user","indexed":true},{"type":"uint256","name":"amount","indexed":false},{"type":"uint256","name":"nonce","indexed":false}],"anonymous":false},{"type":"error","name":"InvalidAmount","inputs":[]},{"type":"error","name":"InvalidNonce","inputs":[]},{"type":"error","name":"NotEnoughFee","inputs":[]}]
              

Contract Creation Code

0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051612f076200012060003960008181610ca101528181610d5101528181610ea601528181610f56015261109b0152612f076000f3fe6080604052600436106101cd5760003560e01c8063894bf962116100f7578063b5c5f67211610095578063d9475dd011610064578063d9475dd0146106d7578063e941fa78146106ea578063f72c0d8b146106ff578063fa8c957c1461073357600080fd5b8063b5c5f67214610603578063c6acb88114610623578063cd68535214610643578063d547741f146106b757600080fd5b806391d14854116100d157806391d14854146105055780639ae5cb5314610558578063a217fddf1461058c578063b2b8cd52146105a157600080fd5b8063894bf962146104b85780638bb5f33e146104cf57806390fd2911146104ef57600080fd5b806336568abe1161016f57806371603b331161013e57806371603b331461037757806380d58366146103ee5780638129fc1c14610483578063827b84831461049857600080fd5b806336568abe1461030f5780633659cfe61461032f5780634f1ef2861461034f57806352d1902d1461036257600080fd5b80631f9bcecc116101ab5780631f9bcecc1461026b578063248a9ca31461029f5780632b6bf8e3146102cf5780632f2ff15d146102ef57600080fd5b806301ffc9a7146101d25780630fcc56f7146102075780631c7265e414610229575b600080fd5b3480156101de57600080fd5b506101f26101ed366004612a2a565b610777565b60405190151581526020015b60405180910390f35b34801561021357600080fd5b50610227610222366004612a6c565b610810565b005b34801561023557600080fd5b5061025d7f824bbb88405251922a737f46ddb8f5ccf95b066b225e8f27f8f493ec8471db2981565b6040519081526020016101fe565b34801561027757600080fd5b5061025d7fcf0909af2648a5468f3142b252ffd7941efb6b92464737587622c7865a33626881565b3480156102ab57600080fd5b5061025d6102ba366004612a6c565b60009081526097602052604090206001015490565b3480156102db57600080fd5b506102276102ea366004612aa7565b61094f565b3480156102fb57600080fd5b5061022761030a366004612afa565b610bad565b34801561031b57600080fd5b5061022761032a366004612afa565b610bd7565b34801561033b57600080fd5b5061022761034a366004612b2a565b610c8a565b61022761035d366004612b76565b610e8f565b34801561036e57600080fd5b5061025d611081565b34801561038357600080fd5b506103d9610392366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff16600090815261012e602090815260409182902082518084019093528054808452600190910154929091018290529091565b604080519283526020830191909152016101fe565b3480156103fa57600080fd5b50610462610409366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff166000908152610131602090815260409182902082516060810184528154808252600183015493820184905260029092015463ffffffff1693018390529092909190565b60408051938452602084019290925263ffffffff16908201526060016101fe565b34801561048f57600080fd5b5061022761116d565b3480156104a457600080fd5b506102276104b3366004612c58565b611350565b3480156104c457600080fd5b5061025d6101335481565b3480156104db57600080fd5b506102276104ea366004612a6c565b611520565b3480156104fb57600080fd5b5061012d5461025d565b34801561051157600080fd5b506101f2610520366004612afa565b600091825260976020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561056457600080fd5b5061025d7f51a4f445a18f75937e90e774151bb35ccc5605812205b0ec93fa2523eaaa551c81565b34801561059857600080fd5b5061025d600081565b3480156105ad57600080fd5b506103d96105bc366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff166000908152610130602090815260409182902082518084019093528054808452600190910154929091018290529091565b34801561060f57600080fd5b5061022761061e366004612c58565b61156e565b34801561062f57600080fd5b5061022761063e366004612aa7565b6118fa565b34801561064f57600080fd5b5061046261065e366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff16600090815261012f602090815260409182902082516060810184528154808252600183015493820184905260029092015463ffffffff1693018390529092909190565b3480156106c357600080fd5b506102276106d2366004612afa565b611b45565b6102276106e5366004612c8d565b611b6a565b3480156106f657600080fd5b50610227611d32565b34801561070b57600080fd5b5061025d7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e381565b34801561073f57600080fd5b5061025d61074e366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff166000908152610132602052604090205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061080a57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b600260015403610881576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600155600061089181611dfb565b6040513390600090829085908381818185875af1925050503d80600081146108d5576040519150601f19603f3d011682016040523d82523d6000602084013e6108da565b606091505b5050905080610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5472616e73666572206661696c65642e000000000000000000000000000000006044820152606401610878565b5050600180555050565b7f51a4f445a18f75937e90e774151bb35ccc5605812205b0ec93fa2523eaaa551c61097981611dfb565b73ffffffffffffffffffffffffffffffffffffffff851660009081526101306020908152604091829020825180840190935280548352600101549082018190528581146109f2576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81518514610a2c576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152610131602090815260409182902082516060810184528154815260018083015493820184905260029092015463ffffffff1693810193909352610a8c908290612cde565b8814610ac4576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825288815260208082018b815263ffffffff808b1684860190815273ffffffffffffffffffffffffffffffffffffffff8f166000818152610131909552938690209451855591516001850155905160029093018054939091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009093169290921790915590517f2244824518082a05f8d58e5a0d72e5fac9e5d02e65d8b3bba47608fae86a238e90610b9a908a908c908b90928352602083019190915263ffffffff16604082015260600190565b60405180910390a2505050505050505050565b600082815260976020526040902060010154610bc881611dfb565b610bd28383611e05565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610c7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610878565b610c868282611ef9565b5050565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163003610d4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610878565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610dc47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614610e67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610878565b610e7081611fb4565b60408051600080825260208201909252610e8c91839190611fde565b50565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163003610f54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610878565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610fc97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461106c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610878565b61107582611fb4565b610c8682826001611fde565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610878565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b600054610100900460ff161580801561118d5750600054600160ff909116105b806111a75750303b1580156111a7575060005460ff166001145b611233576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610878565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561129157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6112996121dd565b6112a16121dd565b6112ac600033611e05565b6112d67f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e333611e05565b6112de612276565b670de0b6b3a764000061012d558015610e8c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b7fcf0909af2648a5468f3142b252ffd7941efb6b92464737587622c7865a33626861137a81611dfb565b73ffffffffffffffffffffffffffffffffffffffff8416600090815261013060209081526040918290208251808401909352805483526001908101549183018290526113c7908290612cde565b85146113ff576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff86166000908152610131602090815260409182902082516060810184528154815260018083015493820184905260029092015463ffffffff169381019390935261145f908290612cde565b8714611497576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825287815260208082018a815273ffffffffffffffffffffffffffffffffffffffff8c166000818152610130845285902093518455905160019093019290925582518981529081018a905290917fdfe39202b2971584d59022626d62f5e78e4b895ebc70d6cd84d4acc893a1f8f1910160405180910390a25050505050505050565b7f824bbb88405251922a737f46ddb8f5ccf95b066b225e8f27f8f493ec8471db2961154a81611dfb565b600082118015611562575068056bc75e2d6310000082105b15610c86575061012d55565b6002600154036115da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610878565b60026001557f824bbb88405251922a737f46ddb8f5ccf95b066b225e8f27f8f493ec8471db2961160981611dfb565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610130602090815260409182902082518084019093528054835260010154908201819052848114611682576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526101316020908152604091829020825160608101845281548152600182015492810183905260029091015463ffffffff169281019290925286811461170f576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518614801590611721575081518614155b15611758576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff88166000908152610132602052604090205461178a906001612cde565b87146117c2576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8816600081815261013260205260408082208a90555190919088908381818185875af1925050503d806000811461182a576040519150601f19603f3d011682016040523d82523d6000602084013e61182f565b606091505b505090508061189a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5472616e73666572206661696c65642e000000000000000000000000000000006044820152606401610878565b60408051888152602081018a905273ffffffffffffffffffffffffffffffffffffffff8b16917f5bb95829671915ece371da722f91d5371159095dcabf2f75cd6c53facb7e1bab910160405180910390a250506001805550505050505050565b7f51a4f445a18f75937e90e774151bb35ccc5605812205b0ec93fa2523eaaa551c61192481611dfb565b73ffffffffffffffffffffffffffffffffffffffff8516600090815261012e60209081526040918290208251808401909352805483526001015490820181905285811461199d576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8716600090815261012f602090815260409182902082516060810184528154815260018083015493820184905260029092015463ffffffff16938101939093526119fd908290612cde565b8814611a35576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518714611a6f576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825288815260208082018b815263ffffffff808b1684860190815273ffffffffffffffffffffffffffffffffffffffff8f16600081815261012f909552938690209451855591516001850155905160029093018054939091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009093169290921790915590517f5cb084c4024dae2725f99ba743881a94c9e1e97dcad4d8a67c43a95d69e6ee8690610b9a908a908c908b90928352602083019190915263ffffffff16604082015260600190565b600082815260976020526040902060010154611b6081611dfb565b610bd28383611ef9565b346000611b7682612315565b90506000611b848284612cf1565b33600090815261012e60209081526040918290208251808401909352805483526001908101549183018290529293509091611bc0908290612cde565b8714611bf8576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815261012f602090815260409182902082516060810184528154815260018083015493820184905260029092015463ffffffff1693810193909352611c42908290612cde565b8914611c7a576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b878514611cb3576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825289815260208082018c815233600090815261012e9092529281209151825591516001909101556101338054889290611cf5908490612cde565b909155505060408051898152602081018b905233917ff3a7dbe2a8983b7ed2ebefd91ae7ab438b66287710e57c83f7cdbacf9af070009101610b9a565b600260015403611d9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610878565b60026001556000611dae81611dfb565b6101338054600091829055604051339290839083908381818185875af1925050503d80600081146108d5576040519150601f19603f3d011682016040523d82523d6000602084013e6108da565b610e8c813361235d565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c8657600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611e9b3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610c8657600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3610c8681611dfb565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561201157610bd28361242f565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612096575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261209391810190612d04565b60015b612122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608401610878565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146121d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152608401610878565b50610bd2838383612539565b600054610100900460ff16612274576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610878565b565b600054610100900460ff1661230d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610878565b612274612564565b600061012d54821015612354576040517f688e55ae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505061012d5490565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c86576123b58173ffffffffffffffffffffffffffffffffffffffff166014612601565b6123c0836020612601565b6040516020016123d1929190612d41565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261087891600401612dc2565b73ffffffffffffffffffffffffffffffffffffffff81163b6124d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610878565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6125428361284b565b60008251118061254f5750805b15610bd25761255e8383612898565b50505050565b600054610100900460ff166125fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610878565b60018055565b60606000612610836002612e13565b61261b906002612cde565b67ffffffffffffffff81111561263357612633612b47565b6040519080825280601f01601f19166020018201604052801561265d576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061269457612694612e2a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106126f7576126f7612e2a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000612733846002612e13565b61273e906001612cde565b90505b60018111156127db577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061277f5761277f612e2a565b1a60f81b82828151811061279557612795612e2a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936127d481612e59565b9050612741565b508315612844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610878565b9392505050565b6128548161242f565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b606073ffffffffffffffffffffffffffffffffffffffff83163b61293e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610878565b6000808473ffffffffffffffffffffffffffffffffffffffff16846040516129669190612e8e565b600060405180830381855af49150503d80600081146129a1576040519150601f19603f3d011682016040523d82523d6000602084013e6129a6565b606091505b50915091506129ce8282604051806060016040528060278152602001612eab602791396129d7565b95945050505050565b606083156129e6575081612844565b8251156129f65782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108789190612dc2565b600060208284031215612a3c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461284457600080fd5b600060208284031215612a7e57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610e8c57600080fd5b60008060008060808587031215612abd57600080fd5b8435612ac881612a85565b93506020850135925060408501359150606085013563ffffffff81168114612aef57600080fd5b939692955090935050565b60008060408385031215612b0d57600080fd5b823591506020830135612b1f81612a85565b809150509250929050565b600060208284031215612b3c57600080fd5b813561284481612a85565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060408385031215612b8957600080fd5b8235612b9481612a85565b9150602083013567ffffffffffffffff80821115612bb157600080fd5b818501915085601f830112612bc557600080fd5b813581811115612bd757612bd7612b47565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612c1d57612c1d612b47565b81604052828152886020848701011115612c3657600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b600080600060608486031215612c6d57600080fd5b8335612c7881612a85565b95602085013595506040909401359392505050565b60008060408385031215612ca057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561080a5761080a612caf565b8181038181111561080a5761080a612caf565b600060208284031215612d1657600080fd5b5051919050565b60005b83811015612d38578181015183820152602001612d20565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612d79816017850160208801612d1d565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351612db6816028840160208801612d1d565b01602801949350505050565b6020815260008251806020840152612de1816040850160208701612d1d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b808202811582820484141761080a5761080a612caf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081612e6857612e68612caf565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60008251612ea0818460208701612d1d565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204f72c48af905d39a1eb54114f4cd91faa5f7ef28cacba5b9d94d4de197df68b664736f6c63430008110033

Deployed ByteCode

0x6080604052600436106101cd5760003560e01c8063894bf962116100f7578063b5c5f67211610095578063d9475dd011610064578063d9475dd0146106d7578063e941fa78146106ea578063f72c0d8b146106ff578063fa8c957c1461073357600080fd5b8063b5c5f67214610603578063c6acb88114610623578063cd68535214610643578063d547741f146106b757600080fd5b806391d14854116100d157806391d14854146105055780639ae5cb5314610558578063a217fddf1461058c578063b2b8cd52146105a157600080fd5b8063894bf962146104b85780638bb5f33e146104cf57806390fd2911146104ef57600080fd5b806336568abe1161016f57806371603b331161013e57806371603b331461037757806380d58366146103ee5780638129fc1c14610483578063827b84831461049857600080fd5b806336568abe1461030f5780633659cfe61461032f5780634f1ef2861461034f57806352d1902d1461036257600080fd5b80631f9bcecc116101ab5780631f9bcecc1461026b578063248a9ca31461029f5780632b6bf8e3146102cf5780632f2ff15d146102ef57600080fd5b806301ffc9a7146101d25780630fcc56f7146102075780631c7265e414610229575b600080fd5b3480156101de57600080fd5b506101f26101ed366004612a2a565b610777565b60405190151581526020015b60405180910390f35b34801561021357600080fd5b50610227610222366004612a6c565b610810565b005b34801561023557600080fd5b5061025d7f824bbb88405251922a737f46ddb8f5ccf95b066b225e8f27f8f493ec8471db2981565b6040519081526020016101fe565b34801561027757600080fd5b5061025d7fcf0909af2648a5468f3142b252ffd7941efb6b92464737587622c7865a33626881565b3480156102ab57600080fd5b5061025d6102ba366004612a6c565b60009081526097602052604090206001015490565b3480156102db57600080fd5b506102276102ea366004612aa7565b61094f565b3480156102fb57600080fd5b5061022761030a366004612afa565b610bad565b34801561031b57600080fd5b5061022761032a366004612afa565b610bd7565b34801561033b57600080fd5b5061022761034a366004612b2a565b610c8a565b61022761035d366004612b76565b610e8f565b34801561036e57600080fd5b5061025d611081565b34801561038357600080fd5b506103d9610392366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff16600090815261012e602090815260409182902082518084019093528054808452600190910154929091018290529091565b604080519283526020830191909152016101fe565b3480156103fa57600080fd5b50610462610409366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff166000908152610131602090815260409182902082516060810184528154808252600183015493820184905260029092015463ffffffff1693018390529092909190565b60408051938452602084019290925263ffffffff16908201526060016101fe565b34801561048f57600080fd5b5061022761116d565b3480156104a457600080fd5b506102276104b3366004612c58565b611350565b3480156104c457600080fd5b5061025d6101335481565b3480156104db57600080fd5b506102276104ea366004612a6c565b611520565b3480156104fb57600080fd5b5061012d5461025d565b34801561051157600080fd5b506101f2610520366004612afa565b600091825260976020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561056457600080fd5b5061025d7f51a4f445a18f75937e90e774151bb35ccc5605812205b0ec93fa2523eaaa551c81565b34801561059857600080fd5b5061025d600081565b3480156105ad57600080fd5b506103d96105bc366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff166000908152610130602090815260409182902082518084019093528054808452600190910154929091018290529091565b34801561060f57600080fd5b5061022761061e366004612c58565b61156e565b34801561062f57600080fd5b5061022761063e366004612aa7565b6118fa565b34801561064f57600080fd5b5061046261065e366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff16600090815261012f602090815260409182902082516060810184528154808252600183015493820184905260029092015463ffffffff1693018390529092909190565b3480156106c357600080fd5b506102276106d2366004612afa565b611b45565b6102276106e5366004612c8d565b611b6a565b3480156106f657600080fd5b50610227611d32565b34801561070b57600080fd5b5061025d7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e381565b34801561073f57600080fd5b5061025d61074e366004612b2a565b73ffffffffffffffffffffffffffffffffffffffff166000908152610132602052604090205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061080a57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b600260015403610881576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600155600061089181611dfb565b6040513390600090829085908381818185875af1925050503d80600081146108d5576040519150601f19603f3d011682016040523d82523d6000602084013e6108da565b606091505b5050905080610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5472616e73666572206661696c65642e000000000000000000000000000000006044820152606401610878565b5050600180555050565b7f51a4f445a18f75937e90e774151bb35ccc5605812205b0ec93fa2523eaaa551c61097981611dfb565b73ffffffffffffffffffffffffffffffffffffffff851660009081526101306020908152604091829020825180840190935280548352600101549082018190528581146109f2576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81518514610a2c576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152610131602090815260409182902082516060810184528154815260018083015493820184905260029092015463ffffffff1693810193909352610a8c908290612cde565b8814610ac4576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825288815260208082018b815263ffffffff808b1684860190815273ffffffffffffffffffffffffffffffffffffffff8f166000818152610131909552938690209451855591516001850155905160029093018054939091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009093169290921790915590517f2244824518082a05f8d58e5a0d72e5fac9e5d02e65d8b3bba47608fae86a238e90610b9a908a908c908b90928352602083019190915263ffffffff16604082015260600190565b60405180910390a2505050505050505050565b600082815260976020526040902060010154610bc881611dfb565b610bd28383611e05565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610c7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610878565b610c868282611ef9565b5050565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000009acd3a79aaeb4301bac0ae5d03ef45e76966132b163003610d4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610878565b7f0000000000000000000000009acd3a79aaeb4301bac0ae5d03ef45e76966132b73ffffffffffffffffffffffffffffffffffffffff16610dc47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614610e67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610878565b610e7081611fb4565b60408051600080825260208201909252610e8c91839190611fde565b50565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000009acd3a79aaeb4301bac0ae5d03ef45e76966132b163003610f54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610878565b7f0000000000000000000000009acd3a79aaeb4301bac0ae5d03ef45e76966132b73ffffffffffffffffffffffffffffffffffffffff16610fc97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff161461106c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610878565b61107582611fb4565b610c8682826001611fde565b60003073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000009acd3a79aaeb4301bac0ae5d03ef45e76966132b1614611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610878565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b600054610100900460ff161580801561118d5750600054600160ff909116105b806111a75750303b1580156111a7575060005460ff166001145b611233576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610878565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561129157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6112996121dd565b6112a16121dd565b6112ac600033611e05565b6112d67f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e333611e05565b6112de612276565b670de0b6b3a764000061012d558015610e8c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b7fcf0909af2648a5468f3142b252ffd7941efb6b92464737587622c7865a33626861137a81611dfb565b73ffffffffffffffffffffffffffffffffffffffff8416600090815261013060209081526040918290208251808401909352805483526001908101549183018290526113c7908290612cde565b85146113ff576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff86166000908152610131602090815260409182902082516060810184528154815260018083015493820184905260029092015463ffffffff169381019390935261145f908290612cde565b8714611497576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825287815260208082018a815273ffffffffffffffffffffffffffffffffffffffff8c166000818152610130845285902093518455905160019093019290925582518981529081018a905290917fdfe39202b2971584d59022626d62f5e78e4b895ebc70d6cd84d4acc893a1f8f1910160405180910390a25050505050505050565b7f824bbb88405251922a737f46ddb8f5ccf95b066b225e8f27f8f493ec8471db2961154a81611dfb565b600082118015611562575068056bc75e2d6310000082105b15610c86575061012d55565b6002600154036115da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610878565b60026001557f824bbb88405251922a737f46ddb8f5ccf95b066b225e8f27f8f493ec8471db2961160981611dfb565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610130602090815260409182902082518084019093528054835260010154908201819052848114611682576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526101316020908152604091829020825160608101845281548152600182015492810183905260029091015463ffffffff169281019290925286811461170f576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518614801590611721575081518614155b15611758576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff88166000908152610132602052604090205461178a906001612cde565b87146117c2576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8816600081815261013260205260408082208a90555190919088908381818185875af1925050503d806000811461182a576040519150601f19603f3d011682016040523d82523d6000602084013e61182f565b606091505b505090508061189a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5472616e73666572206661696c65642e000000000000000000000000000000006044820152606401610878565b60408051888152602081018a905273ffffffffffffffffffffffffffffffffffffffff8b16917f5bb95829671915ece371da722f91d5371159095dcabf2f75cd6c53facb7e1bab910160405180910390a250506001805550505050505050565b7f51a4f445a18f75937e90e774151bb35ccc5605812205b0ec93fa2523eaaa551c61192481611dfb565b73ffffffffffffffffffffffffffffffffffffffff8516600090815261012e60209081526040918290208251808401909352805483526001015490820181905285811461199d576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8716600090815261012f602090815260409182902082516060810184528154815260018083015493820184905260029092015463ffffffff16938101939093526119fd908290612cde565b8814611a35576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83518714611a6f576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825288815260208082018b815263ffffffff808b1684860190815273ffffffffffffffffffffffffffffffffffffffff8f16600081815261012f909552938690209451855591516001850155905160029093018054939091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009093169290921790915590517f5cb084c4024dae2725f99ba743881a94c9e1e97dcad4d8a67c43a95d69e6ee8690610b9a908a908c908b90928352602083019190915263ffffffff16604082015260600190565b600082815260976020526040902060010154611b6081611dfb565b610bd28383611ef9565b346000611b7682612315565b90506000611b848284612cf1565b33600090815261012e60209081526040918290208251808401909352805483526001908101549183018290529293509091611bc0908290612cde565b8714611bf8576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815261012f602090815260409182902082516060810184528154815260018083015493820184905260029092015463ffffffff1693810193909352611c42908290612cde565b8914611c7a576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b878514611cb3576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825289815260208082018c815233600090815261012e9092529281209151825591516001909101556101338054889290611cf5908490612cde565b909155505060408051898152602081018b905233917ff3a7dbe2a8983b7ed2ebefd91ae7ab438b66287710e57c83f7cdbacf9af070009101610b9a565b600260015403611d9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610878565b60026001556000611dae81611dfb565b6101338054600091829055604051339290839083908381818185875af1925050503d80600081146108d5576040519150601f19603f3d011682016040523d82523d6000602084013e6108da565b610e8c813361235d565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c8657600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611e9b3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610c8657600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3610c8681611dfb565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561201157610bd28361242f565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612096575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261209391810190612d04565b60015b612122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608401610878565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146121d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152608401610878565b50610bd2838383612539565b600054610100900460ff16612274576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610878565b565b600054610100900460ff1661230d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610878565b612274612564565b600061012d54821015612354576040517f688e55ae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505061012d5490565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c86576123b58173ffffffffffffffffffffffffffffffffffffffff166014612601565b6123c0836020612601565b6040516020016123d1929190612d41565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261087891600401612dc2565b73ffffffffffffffffffffffffffffffffffffffff81163b6124d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610878565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6125428361284b565b60008251118061254f5750805b15610bd25761255e8383612898565b50505050565b600054610100900460ff166125fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610878565b60018055565b60606000612610836002612e13565b61261b906002612cde565b67ffffffffffffffff81111561263357612633612b47565b6040519080825280601f01601f19166020018201604052801561265d576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061269457612694612e2a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106126f7576126f7612e2a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000612733846002612e13565b61273e906001612cde565b90505b60018111156127db577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061277f5761277f612e2a565b1a60f81b82828151811061279557612795612e2a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936127d481612e59565b9050612741565b508315612844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610878565b9392505050565b6128548161242f565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b606073ffffffffffffffffffffffffffffffffffffffff83163b61293e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610878565b6000808473ffffffffffffffffffffffffffffffffffffffff16846040516129669190612e8e565b600060405180830381855af49150503d80600081146129a1576040519150601f19603f3d011682016040523d82523d6000602084013e6129a6565b606091505b50915091506129ce8282604051806060016040528060278152602001612eab602791396129d7565b95945050505050565b606083156129e6575081612844565b8251156129f65782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108789190612dc2565b600060208284031215612a3c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461284457600080fd5b600060208284031215612a7e57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610e8c57600080fd5b60008060008060808587031215612abd57600080fd5b8435612ac881612a85565b93506020850135925060408501359150606085013563ffffffff81168114612aef57600080fd5b939692955090935050565b60008060408385031215612b0d57600080fd5b823591506020830135612b1f81612a85565b809150509250929050565b600060208284031215612b3c57600080fd5b813561284481612a85565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060408385031215612b8957600080fd5b8235612b9481612a85565b9150602083013567ffffffffffffffff80821115612bb157600080fd5b818501915085601f830112612bc557600080fd5b813581811115612bd757612bd7612b47565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612c1d57612c1d612b47565b81604052828152886020848701011115612c3657600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b600080600060608486031215612c6d57600080fd5b8335612c7881612a85565b95602085013595506040909401359392505050565b60008060408385031215612ca057600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561080a5761080a612caf565b8181038181111561080a5761080a612caf565b600060208284031215612d1657600080fd5b5051919050565b60005b83811015612d38578181015183820152602001612d20565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612d79816017850160208801612d1d565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351612db6816028840160208801612d1d565b01602801949350505050565b6020815260008251806020840152612de1816040850160208701612d1d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b808202811582820484141761080a5761080a612caf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081612e6857612e68612caf565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60008251612ea0818460208701612d1d565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204f72c48af905d39a1eb54114f4cd91faa5f7ef28cacba5b9d94d4de197df68b664736f6c63430008110033