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