false
true
0

Contract Address Details

0x6670cc70a7c54216D327d8Ed0E6b047f6040d925

Contract Name
CexyDexyLocky
Creator
0x4e59b4–b4956c at 0x990c0f–1f0214
Balance
0 tPLS
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
25393880
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
CexyDexyLocky




Optimization enabled
false
Compiler version
v0.8.24+commit.e11b9ed9




EVM Version




Verified at
2026-09-13T15:39:41.933963Z

Constructor Arguments

000000000000000000000000175bcf0cce6c54d842a61a3f94d80c412bceb503

Arg [0] (address) : 0x175bcf0cce6c54d842a61a3f94d80c412bceb503

              

src/CexyDexyLocky.sol

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

/// @title CexyDexyLocky
/// @notice Hash Time Lock Contract for native tokens (ETH on Ethereum, PLS on PulseChain).
///         The same contract is deployed on both chains. Which native token is locked
///         depends only on which chain it is deployed to.
///
/// @dev Flow (ETH → PLS swap):
///      1. User calls lock(H, T2, relayerAddress, auth) on Sepolia, sending ETH
///         H = keccak256(secret), T2 = ETH timelock, relayer receives ETH on claim
///         auth = Lambda-signed quote authorisation (verifies rate, expiry, trusted origin)
///      2. Golang relayer calls lock(H, T1, userAddress, auth) on PulseChain, sending PLS
///         T1 > T2, user receives PLS on claim
///      3. Golang relayer calls claim(ethLockId, secret) on Sepolia — ETH to relayer, secret revealed on-chain
///      4. Golang relayer (or anyone) calls claim(plsLockId, secret) on PulseChain — PLS to user
///
///      Self-custody fallback: if step 4 is skipped, the secret is now public on Sepolia.
///      The user's frontend can read the secret and call claim() on PulseChain directly.
///      Funds always go to the receiver address baked into the lock — the caller of claim()
///      receives nothing for themselves.
///
///      Timelock safety: T1 > T2 guarantees that when the secret is revealed (step 3),
///      the PulseChain lock always has T1 - T2 > 0 time remaining for the user to claim.
///
///      Quote authorization: every lock() call must carry a Lambda signature that commits
///      to all material quote fields (amounts, tokens, expiresAt, hashlock, timelock, …).
///      The contract verifies the signature against trustedSigner and rejects expired or
///      replayed quotes before any funds are locked.
contract CexyDexyLocky {

    address public immutable trustedSigner;

    /// @notice Tracks consumed quoteIds to prevent replay of a signed quote.
    mapping(bytes32 => bool) public usedQuotes;

    struct Lock {
        address sender;    // who locked the funds; receives refund after timelock
        address receiver;  // who receives the funds when claim() is called
        uint256 amount;
        bytes32 hashlock;  // H = keccak256(secret) — commits to secret without revealing it
        uint256 timelock;  // Unix timestamp after which sender can refund
        bool claimed;
        bool refunded;
    }

    /// @notice Authorisation payload that every lock() call must supply.
    ///         All fields are signed by the Lambda backend key (trustedSigner).
    struct QuoteAuthorization {
        bytes32 quoteId;              // keccak256(utf8(uuid)) — unique per quote
        uint256 expiresAt;            // Unix timestamp after which the quote is invalid
        address fromToken;
        uint256 fromAmount;
        address toToken;
        uint256 toAmount;
        uint256 relayerFeeAmount;
        address userDestinationAddress;
        bytes   lambdaSignature;      // 65-byte EIP-191 ECDSA signature
    }

    mapping(bytes32 => Lock) public locks;

    event Locked(
        bytes32 indexed lockId,
        address indexed sender,
        address indexed receiver,
        uint256 amount,
        bytes32 hashlock,
        uint256 timelock
    );

    /// @notice Emitted when claim() is called. The preimage (secret) is now public on-chain.
    event Claimed(bytes32 indexed lockId, bytes32 preimage);

    event Refunded(bytes32 indexed lockId);

    error LockAlreadyExists();
    error LockNotFound();
    error HashlockMismatch();
    error TimelockNotExpired();
    error AlreadyClaimed();
    error AlreadyRefunded();
    error TransferFailed();
    error NoValueSent();
    error TimelockInPast();
    error QuoteExpired();
    error QuoteAlreadyUsed();
    error InvalidQuoteSignature();

    constructor(address _trustedSigner) {
        require(_trustedSigner != address(0), "Zero address");
        trustedSigner = _trustedSigner;
    }

    /// @notice Lock native tokens in the contract.
    /// @param hashlock  H = keccak256(secret). Commits to the secret without revealing it.
    /// @param timelock  Unix timestamp after which the sender can reclaim funds via refund().
    /// @param receiver  Address that receives funds when claim() is called.
    ///                  On Sepolia: the Golang relayer address (receives ETH).
    ///                  On PulseChain: the user's wallet address (receives PLS).
    /// @param auth      Lambda-signed quote authorisation. Checked before any funds are locked
    ///                  so the user never wastes gas on an expired or unauthorised quote.
    /// @return lockId   Unique ID for this lock, derived from sender + hashlock + timelock + timestamp.
    function lock(
        bytes32 hashlock,
        uint256 timelock,
        address receiver,
        QuoteAuthorization calldata auth
    ) external payable returns (bytes32 lockId) {
        if (block.timestamp > auth.expiresAt) revert QuoteExpired();
        if (usedQuotes[auth.quoteId])         revert QuoteAlreadyUsed();

        usedQuotes[auth.quoteId] = true;
        _verifyQuoteSignature(hashlock, timelock, receiver, auth);

        if (msg.value == 0) revert NoValueSent();
        if (timelock <= block.timestamp) revert TimelockInPast();

        lockId = keccak256(
            abi.encodePacked(msg.sender, hashlock, timelock, block.timestamp)
        );
        if (locks[lockId].sender != address(0)) revert LockAlreadyExists();

        locks[lockId] = Lock({
            sender: msg.sender,
            receiver: receiver,
            amount: msg.value,
            hashlock: hashlock,
            timelock: timelock,
            claimed: false,
            refunded: false
        });

        emit Locked(lockId, msg.sender, receiver, msg.value, hashlock, timelock);
    }

    /// @notice Claim locked funds by revealing the secret.
    ///         Anyone can call this — funds always go to lock.receiver regardless of caller.
    ///         Revealing the secret here makes it permanently visible on-chain.
    /// @param lockId   The lock to claim.
    /// @param preimage The secret S where keccak256(S) == lock.hashlock.
    function claim(bytes32 lockId, bytes32 preimage) external {
        Lock storage l = locks[lockId];
        if (l.sender == address(0)) revert LockNotFound();
        if (l.claimed) revert AlreadyClaimed();
        if (l.refunded) revert AlreadyRefunded();
        if (keccak256(abi.encodePacked(preimage)) != l.hashlock) revert HashlockMismatch();

        // Checks-effects-interactions: update state before transfer to prevent re-entrancy
        l.claimed = true;
        emit Claimed(lockId, preimage);

        (bool ok,) = l.receiver.call{value: l.amount}("");
        if (!ok) revert TransferFailed();
    }

    /// @notice Refund locked funds after the timelock has expired.
    ///         Anyone can call this — funds always go back to lock.sender regardless of caller.
    /// @param lockId The lock to refund.
    function refund(bytes32 lockId) external {
        Lock storage l = locks[lockId];
        if (l.sender == address(0)) revert LockNotFound();
        if (l.claimed) revert AlreadyClaimed();
        if (l.refunded) revert AlreadyRefunded();
        if (block.timestamp < l.timelock) revert TimelockNotExpired();

        // Checks-effects-interactions: update state before transfer to prevent re-entrancy
        l.refunded = true;
        emit Refunded(lockId);

        (bool ok,) = l.sender.call{value: l.amount}("");
        if (!ok) revert TransferFailed();
    }

    /// @dev Reconstructs the EIP-191 personal-sign hash that the Lambda backend produced
    ///      (ethers solidityPackedKeccak256 + wallet.signMessage) and checks ecrecover.
    ///      Parameter order and types must stay in sync with quote-signer.ts.
    function _verifyQuoteSignature(
        bytes32 hashlock,
        uint256 timelock,
        address receiver,
        QuoteAuthorization calldata auth
    ) internal view {
        // Split into two packed segments to avoid stack-too-deep; the concatenation is
        // byte-identical to a single abi.encodePacked over all fields.
        bytes32 quoteHash = keccak256(bytes.concat(
            abi.encodePacked(
                auth.quoteId,
                auth.expiresAt,
                auth.fromToken,
                auth.fromAmount,
                auth.toToken,
                auth.toAmount
            ),
            abi.encodePacked(
                hashlock,
                timelock,
                address(this),
                receiver,
                auth.relayerFeeAmount,
                auth.userDestinationAddress,
                block.chainid // domain separation: same address on every chain via CREATE2
            )
        ));
        bytes32 ethSignedHash = keccak256(
            abi.encodePacked("\x19Ethereum Signed Message:\n32", quoteHash)
        );
        if (auth.lambdaSignature.length != 65) revert InvalidQuoteSignature();
        bytes32 r = bytes32(auth.lambdaSignature[:32]);
        bytes32 s = bytes32(auth.lambdaSignature[32:64]);
        uint8   v = uint8(bytes1(auth.lambdaSignature[64:65]));
        address recovered = ecrecover(ethSignedHash, v, r, s);
        if (recovered == address(0) || recovered != trustedSigner) revert InvalidQuoteSignature();
    }
}
        

Compiler Settings

{"viaIR":false,"remappings":["forge-std/=lib/forge-std/src/"],"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode"]}},"optimizer":{"runs":200,"enabled":false},"metadata":{"useLiteralContent":false,"bytecodeHash":"none","appendCBOR":true},"libraries":{},"evmVersion":"cancun"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_trustedSigner","internalType":"address"}]},{"type":"error","name":"AlreadyClaimed","inputs":[]},{"type":"error","name":"AlreadyRefunded","inputs":[]},{"type":"error","name":"HashlockMismatch","inputs":[]},{"type":"error","name":"InvalidQuoteSignature","inputs":[]},{"type":"error","name":"LockAlreadyExists","inputs":[]},{"type":"error","name":"LockNotFound","inputs":[]},{"type":"error","name":"NoValueSent","inputs":[]},{"type":"error","name":"QuoteAlreadyUsed","inputs":[]},{"type":"error","name":"QuoteExpired","inputs":[]},{"type":"error","name":"TimelockInPast","inputs":[]},{"type":"error","name":"TimelockNotExpired","inputs":[]},{"type":"error","name":"TransferFailed","inputs":[]},{"type":"event","name":"Claimed","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"preimage","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"Locked","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"address","name":"receiver","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"bytes32","name":"hashlock","internalType":"bytes32","indexed":false},{"type":"uint256","name":"timelock","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Refunded","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claim","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32"},{"type":"bytes32","name":"preimage","internalType":"bytes32"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32"}],"name":"lock","inputs":[{"type":"bytes32","name":"hashlock","internalType":"bytes32"},{"type":"uint256","name":"timelock","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"},{"type":"tuple","name":"auth","internalType":"struct CexyDexyLocky.QuoteAuthorization","components":[{"type":"bytes32","name":"quoteId","internalType":"bytes32"},{"type":"uint256","name":"expiresAt","internalType":"uint256"},{"type":"address","name":"fromToken","internalType":"address"},{"type":"uint256","name":"fromAmount","internalType":"uint256"},{"type":"address","name":"toToken","internalType":"address"},{"type":"uint256","name":"toAmount","internalType":"uint256"},{"type":"uint256","name":"relayerFeeAmount","internalType":"uint256"},{"type":"address","name":"userDestinationAddress","internalType":"address"},{"type":"bytes","name":"lambdaSignature","internalType":"bytes"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"receiver","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes32","name":"hashlock","internalType":"bytes32"},{"type":"uint256","name":"timelock","internalType":"uint256"},{"type":"bool","name":"claimed","internalType":"bool"},{"type":"bool","name":"refunded","internalType":"bool"}],"name":"locks","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"refund","inputs":[{"type":"bytes32","name":"lockId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"trustedSigner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"usedQuotes","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]}]
              

Contract Creation Code

0x60a060405234801562000010575f80fd5b50604051620018bd380380620018bd833981810160405281019062000036919062000147565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200009e90620001d5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050620001f5565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200011182620000e6565b9050919050565b620001238162000105565b81146200012e575f80fd5b50565b5f81519050620001418162000118565b92915050565b5f602082840312156200015f576200015e620000e2565b5b5f6200016e8482850162000131565b91505092915050565b5f82825260208201905092915050565b7f5a65726f206164647265737300000000000000000000000000000000000000005f82015250565b5f620001bd600c8362000177565b9150620001ca8262000187565b602082019050919050565b5f6020820190508181035f830152620001ee81620001af565b9050919050565b6080516116a8620002155f395f8181610b350152610db101526116a85ff3fe608060405260043610610054575f3560e01c806301df3ea3146100585780637249fbb61461008857806384cc9dfb146100b0578063b9615b1a146100d8578063ed5e843714610114578063f74d548014610156575b5f80fd5b610072600480360381019061006d9190610f2e565b610180565b60405161007f9190610fbd565b60405180910390f35b348015610093575f80fd5b506100ae60048036038101906100a99190610fd6565b610555565b005b3480156100bb575f80fd5b506100d660048036038101906100d19190611001565b6107d3565b005b3480156100e3575f80fd5b506100fe60048036038101906100f99190610fd6565b610a82565b60405161010b9190611059565b60405180910390f35b34801561011f575f80fd5b5061013a60048036038101906101359190610fd6565b610a9e565b60405161014d9796959493929190611090565b60405180910390f35b348015610161575f80fd5b5061016a610b33565b60405161017791906110fd565b60405180910390f35b5f81602001354211156101bf576040517f8727a7f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80835f013581526020019081526020015f205f9054906101000a900460ff1615610216576040517f39c3e39800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015f80845f013581526020019081526020015f205f6101000a81548160ff02191690831515021790555061024d85858585610b57565b5f3403610286576040517f9dce2b3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4284116102bf576040517fbd92345500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b338585426040516020016102d6949392919061119b565b6040516020818303038152906040528051906020012090505f73ffffffffffffffffffffffffffffffffffffffff1660015f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610385576040517f748d150900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060e001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020013481526020018681526020018581526020015f151581526020015f151581525060015f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015f6101000a81548160ff02191690831515021790555060c08201518160050160016101000a81548160ff0219169083151502179055509050508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16827f578af4d125bb96ec89cd1ade591cb196f35d15047d5b096c478e45e311d84263348989604051610545939291906111e8565b60405180910390a4949350505050565b5f60015f8381526020019081526020015f2090505f73ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036105f0576040517fc10ddcde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806005015f9054906101000a900460ff1615610638576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060050160019054906101000a900460ff1615610681576040517fa85e6f1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600401544210156106bf576040517f621e25c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018160050160016101000a81548160ff021916908315150217905550817ffe509803c09416b28ff3d8f690c8b0c61462a892c46d5430c8fb20abe472daf060405160405180910390a25f815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1682600201546040516107549061124a565b5f6040518083038185875af1925050503d805f811461078e576040519150601f19603f3d011682016040523d82523d5f602084013e610793565b606091505b50509050806107ce576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b5f60015f8481526020019081526020015f2090505f73ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361086e576040517fc10ddcde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806005015f9054906101000a900460ff16156108b6576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060050160019054906101000a900460ff16156108ff576040517fa85e6f1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806003015482604051602001610915919061125e565b6040516020818303038152906040528051906020012014610962576040517f7a5cb6ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816005015f6101000a81548160ff021916908315150217905550827f38d6042dbdae8e73a7f6afbabd3fbe0873f9f5ed3cd71294591c3908c2e65fee836040516109ae9190610fbd565b60405180910390a25f816001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260020154604051610a029061124a565b5f6040518083038185875af1925050503d805f8114610a3c576040519150601f19603f3d011682016040523d82523d5f602084013e610a41565b606091505b5050905080610a7c576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b5f602052805f5260405f205f915054906101000a900460ff1681565b6001602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806002015490806003015490806004015490806005015f9054906101000a900460ff16908060050160019054906101000a900460ff16905087565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f815f01358260200135836040016020810190610b749190611278565b8460600135856080016020810190610b8c9190611278565b8660a00135604051602001610ba6969594939291906112a3565b604051602081830303815290604052858530868660c001358760e0016020810190610bd19190611278565b46604051602001610be89796959493929190611312565b604051602081830303815290604052604051602001610c089291906113f4565b6040516020818303038152906040528051906020012090505f81604051602001610c32919061146b565b604051602081830303815290604052805190602001209050604183806101000190610c5d919061149c565b905014610c96576040517f9c584f5400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f83806101000190610ca8919061149c565b5f90602092610cb993929190611506565b90610cc49190611556565b90505f84806101000190610cd8919061149c565b602090604092610cea93929190611506565b90610cf59190611556565b90505f85806101000190610d09919061149c565b604090604192610d1b93929190611506565b90610d2691906115df565b60f81c90505f6001858386866040515f8152602001604052604051610d4e9493929190611658565b6020604051602081039080840390855afa158015610d6e573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e0057507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15610e37576040517f9c584f5400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b5f80fd5b5f80fd5b5f819050919050565b610e5d81610e4b565b8114610e67575f80fd5b50565b5f81359050610e7881610e54565b92915050565b5f819050919050565b610e9081610e7e565b8114610e9a575f80fd5b50565b5f81359050610eab81610e87565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610eda82610eb1565b9050919050565b610eea81610ed0565b8114610ef4575f80fd5b50565b5f81359050610f0581610ee1565b92915050565b5f80fd5b5f6101208284031215610f2557610f24610f0b565b5b81905092915050565b5f805f8060808587031215610f4657610f45610e43565b5b5f610f5387828801610e6a565b9450506020610f6487828801610e9d565b9350506040610f7587828801610ef7565b925050606085013567ffffffffffffffff811115610f9657610f95610e47565b5b610fa287828801610f0f565b91505092959194509250565b610fb781610e4b565b82525050565b5f602082019050610fd05f830184610fae565b92915050565b5f60208284031215610feb57610fea610e43565b5b5f610ff884828501610e6a565b91505092915050565b5f806040838503121561101757611016610e43565b5b5f61102485828601610e6a565b925050602061103585828601610e6a565b9150509250929050565b5f8115159050919050565b6110538161103f565b82525050565b5f60208201905061106c5f83018461104a565b92915050565b61107b81610ed0565b82525050565b61108a81610e7e565b82525050565b5f60e0820190506110a35f83018a611072565b6110b06020830189611072565b6110bd6040830188611081565b6110ca6060830187610fae565b6110d76080830186611081565b6110e460a083018561104a565b6110f160c083018461104a565b98975050505050505050565b5f6020820190506111105f830184611072565b92915050565b5f8160601b9050919050565b5f61112c82611116565b9050919050565b5f61113d82611122565b9050919050565b61115561115082610ed0565b611133565b82525050565b5f819050919050565b61117561117082610e4b565b61115b565b82525050565b5f819050919050565b61119561119082610e7e565b61117b565b82525050565b5f6111a68287611144565b6014820191506111b68286611164565b6020820191506111c68285611184565b6020820191506111d68284611184565b60208201915081905095945050505050565b5f6060820190506111fb5f830186611081565b6112086020830185610fae565b6112156040830184611081565b949350505050565b5f81905092915050565b50565b5f6112355f8361121d565b915061124082611227565b5f82019050919050565b5f6112548261122a565b9150819050919050565b5f6112698284611164565b60208201915081905092915050565b5f6020828403121561128d5761128c610e43565b5b5f61129a84828501610ef7565b91505092915050565b5f6112ae8289611164565b6020820191506112be8288611184565b6020820191506112ce8287611144565b6014820191506112de8286611184565b6020820191506112ee8285611144565b6014820191506112fe8284611184565b602082019150819050979650505050505050565b5f61131d828a611164565b60208201915061132d8289611184565b60208201915061133d8288611144565b60148201915061134d8287611144565b60148201915061135d8286611184565b60208201915061136d8285611144565b60148201915061137d8284611184565b60208201915081905098975050505050505050565b5f81519050919050565b5f5b838110156113b957808201518184015260208101905061139e565b5f8484015250505050565b5f6113ce82611392565b6113d8818561121d565b93506113e881856020860161139c565b80840191505092915050565b5f6113ff82856113c4565b915061140b82846113c4565b91508190509392505050565b5f81905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f82015250565b5f611455601c83611417565b915061146082611421565b601c82019050919050565b5f61147582611449565b91506114818284611164565b60208201915081905092915050565b5f80fd5b5f80fd5b5f80fd5b5f80833560016020038436030381126114b8576114b7611490565b5b80840192508235915067ffffffffffffffff8211156114da576114d9611494565b5b6020830192506001820236038313156114f6576114f5611498565b5b509250929050565b5f80fd5b5f80fd5b5f8085851115611519576115186114fe565b5b8386111561152a57611529611502565b5b6001850283019150848603905094509492505050565b5f82905092915050565b5f82821b905092915050565b5f6115618383611540565b8261156c8135610e4b565b925060208210156115ac576115a77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261154a565b831692505b505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b5f6115ea8383611540565b826115f581356115b4565b92506001821015611635576116307fff000000000000000000000000000000000000000000000000000000000000008360010360080261154a565b831692505b505092915050565b5f60ff82169050919050565b6116528161163d565b82525050565b5f60808201905061166b5f830187610fae565b6116786020830186611649565b6116856040830185610fae565b6116926060830184610fae565b9594505050505056fea164736f6c6343000818000a000000000000000000000000175bcf0cce6c54d842a61a3f94d80c412bceb503

Deployed ByteCode

0x608060405260043610610054575f3560e01c806301df3ea3146100585780637249fbb61461008857806384cc9dfb146100b0578063b9615b1a146100d8578063ed5e843714610114578063f74d548014610156575b5f80fd5b610072600480360381019061006d9190610f2e565b610180565b60405161007f9190610fbd565b60405180910390f35b348015610093575f80fd5b506100ae60048036038101906100a99190610fd6565b610555565b005b3480156100bb575f80fd5b506100d660048036038101906100d19190611001565b6107d3565b005b3480156100e3575f80fd5b506100fe60048036038101906100f99190610fd6565b610a82565b60405161010b9190611059565b60405180910390f35b34801561011f575f80fd5b5061013a60048036038101906101359190610fd6565b610a9e565b60405161014d9796959493929190611090565b60405180910390f35b348015610161575f80fd5b5061016a610b33565b60405161017791906110fd565b60405180910390f35b5f81602001354211156101bf576040517f8727a7f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80835f013581526020019081526020015f205f9054906101000a900460ff1615610216576040517f39c3e39800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015f80845f013581526020019081526020015f205f6101000a81548160ff02191690831515021790555061024d85858585610b57565b5f3403610286576040517f9dce2b3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4284116102bf576040517fbd92345500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b338585426040516020016102d6949392919061119b565b6040516020818303038152906040528051906020012090505f73ffffffffffffffffffffffffffffffffffffffff1660015f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610385576040517f748d150900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060e001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020013481526020018681526020018581526020015f151581526020015f151581525060015f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015f6101000a81548160ff02191690831515021790555060c08201518160050160016101000a81548160ff0219169083151502179055509050508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16827f578af4d125bb96ec89cd1ade591cb196f35d15047d5b096c478e45e311d84263348989604051610545939291906111e8565b60405180910390a4949350505050565b5f60015f8381526020019081526020015f2090505f73ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036105f0576040517fc10ddcde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806005015f9054906101000a900460ff1615610638576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060050160019054906101000a900460ff1615610681576040517fa85e6f1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600401544210156106bf576040517f621e25c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018160050160016101000a81548160ff021916908315150217905550817ffe509803c09416b28ff3d8f690c8b0c61462a892c46d5430c8fb20abe472daf060405160405180910390a25f815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1682600201546040516107549061124a565b5f6040518083038185875af1925050503d805f811461078e576040519150601f19603f3d011682016040523d82523d5f602084013e610793565b606091505b50509050806107ce576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b5f60015f8481526020019081526020015f2090505f73ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361086e576040517fc10ddcde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806005015f9054906101000a900460ff16156108b6576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060050160019054906101000a900460ff16156108ff576040517fa85e6f1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806003015482604051602001610915919061125e565b6040516020818303038152906040528051906020012014610962576040517f7a5cb6ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816005015f6101000a81548160ff021916908315150217905550827f38d6042dbdae8e73a7f6afbabd3fbe0873f9f5ed3cd71294591c3908c2e65fee836040516109ae9190610fbd565b60405180910390a25f816001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260020154604051610a029061124a565b5f6040518083038185875af1925050503d805f8114610a3c576040519150601f19603f3d011682016040523d82523d5f602084013e610a41565b606091505b5050905080610a7c576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b5f602052805f5260405f205f915054906101000a900460ff1681565b6001602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806002015490806003015490806004015490806005015f9054906101000a900460ff16908060050160019054906101000a900460ff16905087565b7f000000000000000000000000175bcf0cce6c54d842a61a3f94d80c412bceb50381565b5f815f01358260200135836040016020810190610b749190611278565b8460600135856080016020810190610b8c9190611278565b8660a00135604051602001610ba6969594939291906112a3565b604051602081830303815290604052858530868660c001358760e0016020810190610bd19190611278565b46604051602001610be89796959493929190611312565b604051602081830303815290604052604051602001610c089291906113f4565b6040516020818303038152906040528051906020012090505f81604051602001610c32919061146b565b604051602081830303815290604052805190602001209050604183806101000190610c5d919061149c565b905014610c96576040517f9c584f5400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f83806101000190610ca8919061149c565b5f90602092610cb993929190611506565b90610cc49190611556565b90505f84806101000190610cd8919061149c565b602090604092610cea93929190611506565b90610cf59190611556565b90505f85806101000190610d09919061149c565b604090604192610d1b93929190611506565b90610d2691906115df565b60f81c90505f6001858386866040515f8152602001604052604051610d4e9493929190611658565b6020604051602081039080840390855afa158015610d6e573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e0057507f000000000000000000000000175bcf0cce6c54d842a61a3f94d80c412bceb50373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15610e37576040517f9c584f5400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b5f80fd5b5f80fd5b5f819050919050565b610e5d81610e4b565b8114610e67575f80fd5b50565b5f81359050610e7881610e54565b92915050565b5f819050919050565b610e9081610e7e565b8114610e9a575f80fd5b50565b5f81359050610eab81610e87565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610eda82610eb1565b9050919050565b610eea81610ed0565b8114610ef4575f80fd5b50565b5f81359050610f0581610ee1565b92915050565b5f80fd5b5f6101208284031215610f2557610f24610f0b565b5b81905092915050565b5f805f8060808587031215610f4657610f45610e43565b5b5f610f5387828801610e6a565b9450506020610f6487828801610e9d565b9350506040610f7587828801610ef7565b925050606085013567ffffffffffffffff811115610f9657610f95610e47565b5b610fa287828801610f0f565b91505092959194509250565b610fb781610e4b565b82525050565b5f602082019050610fd05f830184610fae565b92915050565b5f60208284031215610feb57610fea610e43565b5b5f610ff884828501610e6a565b91505092915050565b5f806040838503121561101757611016610e43565b5b5f61102485828601610e6a565b925050602061103585828601610e6a565b9150509250929050565b5f8115159050919050565b6110538161103f565b82525050565b5f60208201905061106c5f83018461104a565b92915050565b61107b81610ed0565b82525050565b61108a81610e7e565b82525050565b5f60e0820190506110a35f83018a611072565b6110b06020830189611072565b6110bd6040830188611081565b6110ca6060830187610fae565b6110d76080830186611081565b6110e460a083018561104a565b6110f160c083018461104a565b98975050505050505050565b5f6020820190506111105f830184611072565b92915050565b5f8160601b9050919050565b5f61112c82611116565b9050919050565b5f61113d82611122565b9050919050565b61115561115082610ed0565b611133565b82525050565b5f819050919050565b61117561117082610e4b565b61115b565b82525050565b5f819050919050565b61119561119082610e7e565b61117b565b82525050565b5f6111a68287611144565b6014820191506111b68286611164565b6020820191506111c68285611184565b6020820191506111d68284611184565b60208201915081905095945050505050565b5f6060820190506111fb5f830186611081565b6112086020830185610fae565b6112156040830184611081565b949350505050565b5f81905092915050565b50565b5f6112355f8361121d565b915061124082611227565b5f82019050919050565b5f6112548261122a565b9150819050919050565b5f6112698284611164565b60208201915081905092915050565b5f6020828403121561128d5761128c610e43565b5b5f61129a84828501610ef7565b91505092915050565b5f6112ae8289611164565b6020820191506112be8288611184565b6020820191506112ce8287611144565b6014820191506112de8286611184565b6020820191506112ee8285611144565b6014820191506112fe8284611184565b602082019150819050979650505050505050565b5f61131d828a611164565b60208201915061132d8289611184565b60208201915061133d8288611144565b60148201915061134d8287611144565b60148201915061135d8286611184565b60208201915061136d8285611144565b60148201915061137d8284611184565b60208201915081905098975050505050505050565b5f81519050919050565b5f5b838110156113b957808201518184015260208101905061139e565b5f8484015250505050565b5f6113ce82611392565b6113d8818561121d565b93506113e881856020860161139c565b80840191505092915050565b5f6113ff82856113c4565b915061140b82846113c4565b91508190509392505050565b5f81905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f82015250565b5f611455601c83611417565b915061146082611421565b601c82019050919050565b5f61147582611449565b91506114818284611164565b60208201915081905092915050565b5f80fd5b5f80fd5b5f80fd5b5f80833560016020038436030381126114b8576114b7611490565b5b80840192508235915067ffffffffffffffff8211156114da576114d9611494565b5b6020830192506001820236038313156114f6576114f5611498565b5b509250929050565b5f80fd5b5f80fd5b5f8085851115611519576115186114fe565b5b8386111561152a57611529611502565b5b6001850283019150848603905094509492505050565b5f82905092915050565b5f82821b905092915050565b5f6115618383611540565b8261156c8135610e4b565b925060208210156115ac576115a77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261154a565b831692505b505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b5f6115ea8383611540565b826115f581356115b4565b92506001821015611635576116307fff000000000000000000000000000000000000000000000000000000000000008360010360080261154a565b831692505b505092915050565b5f60ff82169050919050565b6116528161163d565b82525050565b5f60808201905061166b5f830187610fae565b6116786020830186611649565b6116856040830185610fae565b6116926060830184610fae565b9594505050505056fea164736f6c6343000818000a