false
false
0
The new Blockscout UI is now open source! Learn how to deploy it here
- We're indexing this chain right now. Some of the counts may be inaccurate.

Contract Address Details

0x08f32278B2CFD962444ae9541122eD84cc745678

Contract Name
Heed
Creator
0x327fa3–a7c458 at 0x2e9d3f–e4927c
Balance
0 ETH
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
6233084
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Heed




Optimization enabled
true
Compiler version
v0.8.27+commit.40a35a09




Optimization runs
1000000
EVM Version
shanghai




Verified at
2026-04-28T05:54:18.961352Z

Constructor Arguments

0x0000000000000000000000000000000000000000000000000000000000989680

Arg [0] (uint32) : 10000000

              

impl/Heed.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;

import {IHeed} from "iface/IHeed.sol";

contract Heed is IHeed {
    uint32 public immutable MAX_FEE_GWEI;

    mapping(address => EncKey[2])                       internal  _keys;
    mapping(address => uint32)                          public    feeGwei;
    mapping(address => mapping(address => bool))        public    trusts;
    mapping(address => address)                         public    delegateOwner;
    mapping(address => bytes32)                         public    delegateClient;

    constructor(uint32 maxFeeGwei) {
        MAX_FEE_GWEI = maxFeeGwei;
    }

    function publishKey(uint32 keyNonce, bytes32 pub) external {
        if (pub == bytes32(0)) revert EmptyPubKey();
        EncKey[2] storage slots = _keys[msg.sender];
        uint32 highest = slots[0].keyNonce > slots[1].keyNonce ? slots[0].keyNonce : slots[1].keyNonce;
        bool firstEverSlot = slots[0].pub == bytes32(0) && slots[1].pub == bytes32(0);
        if (!firstEverSlot && keyNonce <= highest) revert KeyNonceNotMonotonic(keyNonce, highest);

        uint8 victim;
        if (slots[0].pub == bytes32(0)) {
            victim = 0;
        } else if (slots[1].pub == bytes32(0)) {
            victim = 1;
        } else {
            victim = slots[0].keyNonce <= slots[1].keyNonce ? 0 : 1;
        }
        slots[victim] = EncKey({keyNonce: keyNonce, publishedAt: uint64(block.timestamp), pub: pub});
        emit KeyPublished(msg.sender, keyNonce, pub);
    }

    function getKeys(address owner) external view returns (EncKey[2] memory) {
        return _keys[owner];
    }

    function setFee(uint32 valueGwei) external {
        if (valueGwei > MAX_FEE_GWEI) revert FeeAboveCap(valueGwei, MAX_FEE_GWEI);
        feeGwei[msg.sender] = valueGwei;
        emit FeeUpdated(msg.sender, valueGwei);
    }
    function trust(address[] calldata senders) external {
        for (uint256 i; i < senders.length; ++i) {
            trusts[msg.sender][senders[i]] = true;
            emit Trusted(msg.sender, senders[i], true);
        }
    }

    function untrust(address[] calldata senders) external {
        for (uint256 i; i < senders.length; ++i) {
            trusts[msg.sender][senders[i]] = false;
            emit Trusted(msg.sender, senders[i], false);
        }
    }
    function registerDelegate(
        address delegate,
        bytes32 clientId,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable {
        if (delegate == address(0)) revert InvalidDelegateSignature();
        bytes32 digest = keccak256(
            abi.encode(
                bytes32("heed.delegate.v1"),
                block.chainid,
                address(this),
                msg.sender,
                delegate,
                clientId
            )
        );
        if (ecrecover(digest, v, r, s) != delegate) revert InvalidDelegateSignature();

        delegateOwner[delegate] = msg.sender;
        delegateClient[delegate] = clientId;
        emit DelegateRegistered(msg.sender, delegate, clientId);
        if (msg.value > 0) {
            (bool ok, ) = delegate.call{value: msg.value}("");
            require(ok, "fund-fail");
        }
    }

    function revokeDelegate(address delegate) external {
        require(delegateOwner[delegate] == msg.sender, "not-owner");
        address owner = msg.sender;
        delete delegateOwner[delegate];
        delete delegateClient[delegate];
        emit DelegateRevoked(owner, delegate);
    }

    function revokeMyself() external {
        address owner = delegateOwner[msg.sender];
        if (owner == address(0)) revert NotADelegate();
        delete delegateOwner[msg.sender];
        delete delegateClient[msg.sender];
        emit DelegateRevoked(owner, msg.sender);
    }
    function sendBatch(MailIntent[] calldata mails, bool atomic) external payable {
        address effectiveSender = delegateOwner[msg.sender] == address(0) ? msg.sender : delegateOwner[msg.sender];
        uint256 spent;

        for (uint256 i; i < mails.length; ++i) {
            MailIntent calldata m = mails[i];
            uint32 required = trusts[m.recipient][effectiveSender] ? 0 : feeGwei[m.recipient];

            if (m.valueGwei < required) {
                if (atomic) revert MailFailed(i);
                continue;
            }

            uint256 valueWei = uint256(m.valueGwei) * 1 gwei;
            if (spent + valueWei > msg.value) {
                if (atomic) revert InsufficientValue(spent + valueWei, msg.value);
                continue;
            }

            (bool ok, ) = m.recipient.call{value: valueWei}("");
            if (!ok) {
                if (atomic) revert MailFailed(i);
                continue;
            }

            spent += valueWei;
            emit MailSent(effectiveSender, m.recipient, m.contentRef, m.valueGwei);
        }

        if (msg.value > spent) {
            (bool ok, ) = msg.sender.call{value: msg.value - spent}("");
            require(ok, "refund-fail");
        }
    }
    function getInbox(address addr) public view returns (InboxView memory) {
        return InboxView({feeGwei: feeGwei[addr], keys: _keys[addr]});
    }

    function getInboxes(address[] calldata addrs) external view returns (InboxView[] memory out) {
        out = new InboxView[](addrs.length);
        for (uint256 i; i < addrs.length; ++i) out[i] = getInbox(addrs[i]);
    }
}
        

iface/IHeed.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;

interface IHeed {
    struct EncKey {
        uint32  keyNonce;
        uint64  publishedAt;
        bytes32 pub;
    }

    struct MailIntent {
        address recipient;
        uint32  valueGwei;
        bytes32 contentRef;
    }

    struct InboxView {
        uint32    feeGwei;
        EncKey[2] keys;
    }

    event KeyPublished(address indexed owner, uint32 keyNonce, bytes32 pub);
    event FeeUpdated(address indexed recipient, uint32 valueGwei);
    event Trusted(address indexed recipient, address indexed sender, bool trusted);
    event DelegateRegistered(address indexed owner, address indexed delegate, bytes32 clientId);
    event DelegateRevoked(address indexed owner, address indexed delegate);
    event MailSent(
        address indexed sender,
        address indexed recipient,
        bytes32 contentRef,
        uint32  valueGwei
    );

    error FeeAboveCap(uint32 valueGwei, uint32 cap);
    error KeyNonceNotMonotonic(uint32 provided, uint32 highest);
    error NotADelegate();
    error InsufficientValue(uint256 sumOfValues, uint256 msgValue);
    error MailFailed(uint256 index);
    error EmptyPubKey();
    error InvalidDelegateSignature();

    function MAX_FEE_GWEI() external view returns (uint32);
    function publishKey(uint32 keyNonce, bytes32 pub) external;
    function getKeys(address owner) external view returns (EncKey[2] memory);
    function setFee(uint32 valueGwei) external;
    function feeGwei(address) external view returns (uint32);
    function trust(address[] calldata senders) external;
    function untrust(address[] calldata senders) external;
    function trusts(address recipient, address sender) external view returns (bool);
    function registerDelegate(
        address delegate,
        bytes32 clientId,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable;
    function revokeDelegate(address delegate) external;
    function revokeMyself() external;
    function delegateOwner(address delegate) external view returns (address);
    function delegateClient(address delegate) external view returns (bytes32);
    function sendBatch(MailIntent[] calldata mails, bool atomic) external payable;
    function getInbox(address addr) external view returns (InboxView memory);
    function getInboxes(address[] calldata addrs) external view returns (InboxView[] memory);
}
          

Compiler Settings

{"viaIR":true,"remappings":["forge-std/=lib/forge-std/src/","impl/=impl/","iface/=iface/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":1000000,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"shanghai"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"uint32","name":"maxFeeGwei","internalType":"uint32"}]},{"type":"error","name":"EmptyPubKey","inputs":[]},{"type":"error","name":"FeeAboveCap","inputs":[{"type":"uint32","name":"valueGwei","internalType":"uint32"},{"type":"uint32","name":"cap","internalType":"uint32"}]},{"type":"error","name":"InsufficientValue","inputs":[{"type":"uint256","name":"sumOfValues","internalType":"uint256"},{"type":"uint256","name":"msgValue","internalType":"uint256"}]},{"type":"error","name":"InvalidDelegateSignature","inputs":[]},{"type":"error","name":"KeyNonceNotMonotonic","inputs":[{"type":"uint32","name":"provided","internalType":"uint32"},{"type":"uint32","name":"highest","internalType":"uint32"}]},{"type":"error","name":"MailFailed","inputs":[{"type":"uint256","name":"index","internalType":"uint256"}]},{"type":"error","name":"NotADelegate","inputs":[]},{"type":"event","name":"DelegateRegistered","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"delegate","internalType":"address","indexed":true},{"type":"bytes32","name":"clientId","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"DelegateRevoked","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"delegate","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"FeeUpdated","inputs":[{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint32","name":"valueGwei","internalType":"uint32","indexed":false}],"anonymous":false},{"type":"event","name":"KeyPublished","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"uint32","name":"keyNonce","internalType":"uint32","indexed":false},{"type":"bytes32","name":"pub","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"MailSent","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"bytes32","name":"contentRef","internalType":"bytes32","indexed":false},{"type":"uint32","name":"valueGwei","internalType":"uint32","indexed":false}],"anonymous":false},{"type":"event","name":"Trusted","inputs":[{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"bool","name":"trusted","internalType":"bool","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"MAX_FEE_GWEI","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"delegateClient","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"delegateOwner","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"feeGwei","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IHeed.InboxView","components":[{"type":"uint32","name":"feeGwei","internalType":"uint32"},{"type":"tuple[2]","name":"keys","internalType":"struct IHeed.EncKey[2]","components":[{"type":"uint32","name":"keyNonce","internalType":"uint32"},{"type":"uint64","name":"publishedAt","internalType":"uint64"},{"type":"bytes32","name":"pub","internalType":"bytes32"}]}]}],"name":"getInbox","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"out","internalType":"struct IHeed.InboxView[]","components":[{"type":"uint32","name":"feeGwei","internalType":"uint32"},{"type":"tuple[2]","name":"keys","internalType":"struct IHeed.EncKey[2]","components":[{"type":"uint32","name":"keyNonce","internalType":"uint32"},{"type":"uint64","name":"publishedAt","internalType":"uint64"},{"type":"bytes32","name":"pub","internalType":"bytes32"}]}]}],"name":"getInboxes","inputs":[{"type":"address[]","name":"addrs","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[2]","name":"","internalType":"struct IHeed.EncKey[2]","components":[{"type":"uint32","name":"keyNonce","internalType":"uint32"},{"type":"uint64","name":"publishedAt","internalType":"uint64"},{"type":"bytes32","name":"pub","internalType":"bytes32"}]}],"name":"getKeys","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"publishKey","inputs":[{"type":"uint32","name":"keyNonce","internalType":"uint32"},{"type":"bytes32","name":"pub","internalType":"bytes32"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"registerDelegate","inputs":[{"type":"address","name":"delegate","internalType":"address"},{"type":"bytes32","name":"clientId","internalType":"bytes32"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeDelegate","inputs":[{"type":"address","name":"delegate","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeMyself","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"sendBatch","inputs":[{"type":"tuple[]","name":"mails","internalType":"struct IHeed.MailIntent[]","components":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint32","name":"valueGwei","internalType":"uint32"},{"type":"bytes32","name":"contentRef","internalType":"bytes32"}]},{"type":"bool","name":"atomic","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFee","inputs":[{"type":"uint32","name":"valueGwei","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"trust","inputs":[{"type":"address[]","name":"senders","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"trusts","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"untrust","inputs":[{"type":"address[]","name":"senders","internalType":"address[]"}]}]
              

Contract Creation Code

Verify & Publish
0x60a034606a57601f61171438819003918201601f19168301916001600160401b03831184841017606e57808492602094604052833981010312606a575163ffffffff81168103606a5760805260405161169190816100838239608051818181610ae80152610cd40152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040526004361015610011575f80fd5b5f5f3560e01c80630220168114611231578063184ba9a714610fe357806319447b5914610d915780631ab971ab14610c9457806334e80c3414610bd4578063430ae46914610b6f578063561aaa0314610b0c578063950e75f414610aad57806397c59b9f14610a155780639e03d01e1461092c578063aa38319a14610856578063b68f68bc14610782578063d44af25614610677578063dcb67dc51461060e578063e5497c86146102095763fa352c00146100ca575f80fd5b346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff61011661127c565b16808252600360205273ffffffffffffffffffffffffffffffffffffffff60408320541633036101a8578082526003602052604082207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558082526004602052816040812055337f76e6646868d096078ac7f3f1401c3aaa55dc84890ec74b99c699e4754714b18e8380a380f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6e6f742d6f776e657200000000000000000000000000000000000000000000006044820152fd5b80fd5b5060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065760043567ffffffffffffffff811161060a573660238201121561060a5780600401359067ffffffffffffffff8211610606573660246060840283010111610606576024358015158103610602573384526003602052604084205473ffffffffffffffffffffffffffffffffffffffff166105d95733915b8490855b8581101561051f57606081028201602481019373ffffffffffffffffffffffffffffffffffffffff6102e0866115c3565b16895260026020526040892073ffffffffffffffffffffffffffffffffffffffff88165f5260205260ff60405f2054165f146104e85788905b86604484019263ffffffff8061032e86611610565b92169116106104d7575063ffffffff61034683611610565b1690633b9aca00820291808304633b9aca0014901517156104aa57873461036d8484611621565b1161045e578b808080866103808d6115c3565b5af161038a611556565b501561042157509163ffffffff6103cc6103c66103c073ffffffffffffffffffffffffffffffffffffffff956001999897611621565b996115c3565b92611610565b6064604051950135855216602084015216907f6670e7276ccbaffc9cb8b4c6c02179e6d89aae16fe663927529a4db6cc013173604073ffffffffffffffffffffffffffffffffffffffff8a1692a35b016102af565b9350955050506104335760019061041b565b7f8fa810ca000000000000000000000000000000000000000000000000000000008752600452602486fd5b925095509150610471575060019061041b565b8761047e60449286611621565b7f7040b58c00000000000000000000000000000000000000000000000000000000825260045234602452fd5b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b92509450506104335760019061041b565b73ffffffffffffffffffffffffffffffffffffffff610506866115c3565b168952600160205263ffffffff60408a20541690610319565b868380341161052c575080f35b34033481116105ac578180808093335af1610545611556565b501561054e5780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f726566756e642d6661696c0000000000000000000000000000000000000000006044820152fd5b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b338452600360205273ffffffffffffffffffffffffffffffffffffffff604085205416916102ab565b8380fd5b8280fd5b5080fd5b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065763ffffffff604060209273ffffffffffffffffffffffffffffffffffffffff61066561127c565b16815260018452205416604051908152f35b50346102065761068636611318565b90610690826115e4565b9161069e60405193846113ef565b8083527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06106cb826115e4565b01845b81811061076b575050835b818110610731578385604051918291602083016020845282518091526020604085019301915b81811061070d575050500390f35b91935091602060e082610723600194885161129f565b0194019101918493926106ff565b8061074f61074a61074560019486886115b3565b6115c3565b6114f9565b61075982876115fc565b5261076481866115fc565b50016106d9565b602090610776611476565b828288010152016106ce565b50346102065761079136611318565b825b81811061079e578380f35b60019033855260026020526040852073ffffffffffffffffffffffffffffffffffffffff6107d06107458487896115b3565b165f5260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00815416905573ffffffffffffffffffffffffffffffffffffffff6108236107458386886115b3565b166040518681527f0a0312df153a43bbacc69017600fd2d548d9f4529e7b80a0a5ec6ed89e2b287e60203392a301610793565b50346102065761086536611318565b825b818110610872578380f35b60019033855260026020526040852073ffffffffffffffffffffffffffffffffffffffff6108a46107458487896115b3565b165f5260205260405f20827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff6108f96107458386886115b3565b166040518381527f0a0312df153a43bbacc69017600fd2d548d9f4529e7b80a0a5ec6ed89e2b287e60203392a301610867565b503461020657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657338152600360205273ffffffffffffffffffffffffffffffffffffffff60408220541680156109ed573382526003602052604082207fffffffffffffffffffffffff00000000000000000000000000000000000000008154169055338252600460205281604081205533907f76e6646868d096078ac7f3f1401c3aaa55dc84890ec74b99c699e4754714b18e8380a380f35b6004827fa0ada974000000000000000000000000000000000000000000000000000000008152fd5b50346102065760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610a4d61127c565b906024359173ffffffffffffffffffffffffffffffffffffffff8316830361060a5773ffffffffffffffffffffffffffffffffffffffff918260409216815260026020522091165f52602052602060ff60405f2054166040519015158152f35b503461020657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657602060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657604060209173ffffffffffffffffffffffffffffffffffffffff610b5e61127c565b168152600483522054604051908152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff604060209282610bc261127c565b16815260038452205416604051908152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff610c2161127c565b610c29611430565b5016815280602052610c3d60408220611496565b60405191825b60028210610c505760c084f35b6020610c89600192855190604060609263ffffffff815116835267ffffffffffffffff6020820151166020840152015160408201520190565b930191019091610c43565b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610ccc611305565b63ffffffff807f000000000000000000000000000000000000000000000000000000000000000016911690808211610d625750338252600160205260408220817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008254161790556040519081527fb3d0d1c9055b5559806e0c3b8634f9bea1690bd00116173edd11aa20ac9ef09460203392a280f35b82917ff6afaf9d0000000000000000000000000000000000000000000000000000000060449452600452602452fd5b5060a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610dc461127c565b906024359160443560ff81168091036106065773ffffffffffffffffffffffffffffffffffffffff8216908115610fbb57836080602092604051848101907f686565642e64656c65676174652e763100000000000000000000000000000000825246604082015230606082015233848201528660a08201528960c082015260c08152610e5160e0826113ef565b51902090604051918252848201526064356040820152608435606082015282805260015afa15610fb0578073ffffffffffffffffffffffffffffffffffffffff84511603610f88578293818452600360205260408420337fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905581845260046020528060408520556040519081527f2b567f02d0528bcc32125a590269fabe81d4ca2e26e34e07a49774f9f065efcd60203392a334610f115750f35b8180809234905af1610f21611556565b5015610f2a5780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f66756e642d6661696c00000000000000000000000000000000000000000000006044820152fd5b6004837ffdf4e6f9000000000000000000000000000000000000000000000000000000008152fd5b6040513d84823e3d90fd5b6004847ffdf4e6f9000000000000000000000000000000000000000000000000000000008152fd5b3461122d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261122d5761101a611305565b602435801561120557335f525f60205260405f209163ffffffff83541663ffffffff6002850154169081811191825f146111fe57505b6001850154159081806111f2575b15806111dc575b6111a457501561118257505f5b63ffffffff604051926110848461138a565b16938483526020830167ffffffffffffffff42168152604084019185835260028410156111555763ffffffff8091600195861b01955116167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000855416178455517fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff6bffffffffffffffff0000000085549260201b1691161783555191015560405191825260208201527fdd57986ec96d909dc3ef348b416fe63afd6585502597be317db0bb1d5b7c366360403392a2005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b600384015461119357506001611072565b61119d575f611072565b6001611072565b63ffffffff9081857fe6c06aa1000000000000000000000000000000000000000000000000000000005f52166004521660245260445ffd5b5063ffffffff811663ffffffff85161115611065565b5060038601541561105e565b9050611050565b7ffc9be71c000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f80fd5b3461122d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261122d5760e061126d61074a61127c565b61127a604051809261129f565bf35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361122d57565b6020809163ffffffff8151168452015191015f905b600282106112c157505050565b60206112fa600192855190604060609263ffffffff815116835267ffffffffffffffff6020820151166020840152015160408201520190565b9301910190916112b4565b6004359063ffffffff8216820361122d57565b9060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261122d5760043567ffffffffffffffff811161122d578260238201121561122d5780600401359267ffffffffffffffff841161122d5760248460051b8301011161122d576024019190565b6060810190811067ffffffffffffffff8211176113a657604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040810190811067ffffffffffffffff8211176113a657604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113a657604052565b60408051919061144081846113ef565b825f5b82811061144f57505050565b60209060405161145e8161138a565b5f81525f838201525f60408201528184015201611443565b60405190611483826113d3565b815f81526020611491611430565b910152565b90604051916114a4836113d3565b5f835b600282106114b457505050565b600260206001926040516114c78161138a565b67ffffffffffffffff875463ffffffff81168352841c16838201528487015460408201528152019301910190916114a7565b73ffffffffffffffffffffffffffffffffffffffff90611517611476565b5016805f52600160205263ffffffff60405f205416905f525f60205261154e60405f2060405192611547846113d3565b8352611496565b602082015290565b3d156115ae573d9067ffffffffffffffff82116113a657604051916115a360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601846113ef565b82523d5f602084013e565b606090565b91908110156111555760051b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361122d5790565b67ffffffffffffffff81116113a65760051b60200190565b80518210156111555760209160051b010190565b3563ffffffff8116810361122d5790565b9190820180921161162e57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffdfea2646970667358221220236b5fdac362bf9430c9284c4a3de2a26513c7a763b0498c5fd84d9e2de3781064736f6c634300081b00330000000000000000000000000000000000000000000000000000000000989680

Deployed ByteCode

0x60806040526004361015610011575f80fd5b5f5f3560e01c80630220168114611231578063184ba9a714610fe357806319447b5914610d915780631ab971ab14610c9457806334e80c3414610bd4578063430ae46914610b6f578063561aaa0314610b0c578063950e75f414610aad57806397c59b9f14610a155780639e03d01e1461092c578063aa38319a14610856578063b68f68bc14610782578063d44af25614610677578063dcb67dc51461060e578063e5497c86146102095763fa352c00146100ca575f80fd5b346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff61011661127c565b16808252600360205273ffffffffffffffffffffffffffffffffffffffff60408320541633036101a8578082526003602052604082207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558082526004602052816040812055337f76e6646868d096078ac7f3f1401c3aaa55dc84890ec74b99c699e4754714b18e8380a380f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6e6f742d6f776e657200000000000000000000000000000000000000000000006044820152fd5b80fd5b5060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065760043567ffffffffffffffff811161060a573660238201121561060a5780600401359067ffffffffffffffff8211610606573660246060840283010111610606576024358015158103610602573384526003602052604084205473ffffffffffffffffffffffffffffffffffffffff166105d95733915b8490855b8581101561051f57606081028201602481019373ffffffffffffffffffffffffffffffffffffffff6102e0866115c3565b16895260026020526040892073ffffffffffffffffffffffffffffffffffffffff88165f5260205260ff60405f2054165f146104e85788905b86604484019263ffffffff8061032e86611610565b92169116106104d7575063ffffffff61034683611610565b1690633b9aca00820291808304633b9aca0014901517156104aa57873461036d8484611621565b1161045e578b808080866103808d6115c3565b5af161038a611556565b501561042157509163ffffffff6103cc6103c66103c073ffffffffffffffffffffffffffffffffffffffff956001999897611621565b996115c3565b92611610565b6064604051950135855216602084015216907f6670e7276ccbaffc9cb8b4c6c02179e6d89aae16fe663927529a4db6cc013173604073ffffffffffffffffffffffffffffffffffffffff8a1692a35b016102af565b9350955050506104335760019061041b565b7f8fa810ca000000000000000000000000000000000000000000000000000000008752600452602486fd5b925095509150610471575060019061041b565b8761047e60449286611621565b7f7040b58c00000000000000000000000000000000000000000000000000000000825260045234602452fd5b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b92509450506104335760019061041b565b73ffffffffffffffffffffffffffffffffffffffff610506866115c3565b168952600160205263ffffffff60408a20541690610319565b868380341161052c575080f35b34033481116105ac578180808093335af1610545611556565b501561054e5780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f726566756e642d6661696c0000000000000000000000000000000000000000006044820152fd5b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b338452600360205273ffffffffffffffffffffffffffffffffffffffff604085205416916102ab565b8380fd5b8280fd5b5080fd5b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065763ffffffff604060209273ffffffffffffffffffffffffffffffffffffffff61066561127c565b16815260018452205416604051908152f35b50346102065761068636611318565b90610690826115e4565b9161069e60405193846113ef565b8083527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06106cb826115e4565b01845b81811061076b575050835b818110610731578385604051918291602083016020845282518091526020604085019301915b81811061070d575050500390f35b91935091602060e082610723600194885161129f565b0194019101918493926106ff565b8061074f61074a61074560019486886115b3565b6115c3565b6114f9565b61075982876115fc565b5261076481866115fc565b50016106d9565b602090610776611476565b828288010152016106ce565b50346102065761079136611318565b825b81811061079e578380f35b60019033855260026020526040852073ffffffffffffffffffffffffffffffffffffffff6107d06107458487896115b3565b165f5260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00815416905573ffffffffffffffffffffffffffffffffffffffff6108236107458386886115b3565b166040518681527f0a0312df153a43bbacc69017600fd2d548d9f4529e7b80a0a5ec6ed89e2b287e60203392a301610793565b50346102065761086536611318565b825b818110610872578380f35b60019033855260026020526040852073ffffffffffffffffffffffffffffffffffffffff6108a46107458487896115b3565b165f5260205260405f20827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff6108f96107458386886115b3565b166040518381527f0a0312df153a43bbacc69017600fd2d548d9f4529e7b80a0a5ec6ed89e2b287e60203392a301610867565b503461020657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657338152600360205273ffffffffffffffffffffffffffffffffffffffff60408220541680156109ed573382526003602052604082207fffffffffffffffffffffffff00000000000000000000000000000000000000008154169055338252600460205281604081205533907f76e6646868d096078ac7f3f1401c3aaa55dc84890ec74b99c699e4754714b18e8380a380f35b6004827fa0ada974000000000000000000000000000000000000000000000000000000008152fd5b50346102065760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610a4d61127c565b906024359173ffffffffffffffffffffffffffffffffffffffff8316830361060a5773ffffffffffffffffffffffffffffffffffffffff918260409216815260026020522091165f52602052602060ff60405f2054166040519015158152f35b503461020657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657602060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000989680168152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657604060209173ffffffffffffffffffffffffffffffffffffffff610b5e61127c565b168152600483522054604051908152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff604060209282610bc261127c565b16815260038452205416604051908152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff610c2161127c565b610c29611430565b5016815280602052610c3d60408220611496565b60405191825b60028210610c505760c084f35b6020610c89600192855190604060609263ffffffff815116835267ffffffffffffffff6020820151166020840152015160408201520190565b930191019091610c43565b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610ccc611305565b63ffffffff807f000000000000000000000000000000000000000000000000000000000098968016911690808211610d625750338252600160205260408220817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008254161790556040519081527fb3d0d1c9055b5559806e0c3b8634f9bea1690bd00116173edd11aa20ac9ef09460203392a280f35b82917ff6afaf9d0000000000000000000000000000000000000000000000000000000060449452600452602452fd5b5060a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610dc461127c565b906024359160443560ff81168091036106065773ffffffffffffffffffffffffffffffffffffffff8216908115610fbb57836080602092604051848101907f686565642e64656c65676174652e763100000000000000000000000000000000825246604082015230606082015233848201528660a08201528960c082015260c08152610e5160e0826113ef565b51902090604051918252848201526064356040820152608435606082015282805260015afa15610fb0578073ffffffffffffffffffffffffffffffffffffffff84511603610f88578293818452600360205260408420337fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905581845260046020528060408520556040519081527f2b567f02d0528bcc32125a590269fabe81d4ca2e26e34e07a49774f9f065efcd60203392a334610f115750f35b8180809234905af1610f21611556565b5015610f2a5780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f66756e642d6661696c00000000000000000000000000000000000000000000006044820152fd5b6004837ffdf4e6f9000000000000000000000000000000000000000000000000000000008152fd5b6040513d84823e3d90fd5b6004847ffdf4e6f9000000000000000000000000000000000000000000000000000000008152fd5b3461122d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261122d5761101a611305565b602435801561120557335f525f60205260405f209163ffffffff83541663ffffffff6002850154169081811191825f146111fe57505b6001850154159081806111f2575b15806111dc575b6111a457501561118257505f5b63ffffffff604051926110848461138a565b16938483526020830167ffffffffffffffff42168152604084019185835260028410156111555763ffffffff8091600195861b01955116167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000855416178455517fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff6bffffffffffffffff0000000085549260201b1691161783555191015560405191825260208201527fdd57986ec96d909dc3ef348b416fe63afd6585502597be317db0bb1d5b7c366360403392a2005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b600384015461119357506001611072565b61119d575f611072565b6001611072565b63ffffffff9081857fe6c06aa1000000000000000000000000000000000000000000000000000000005f52166004521660245260445ffd5b5063ffffffff811663ffffffff85161115611065565b5060038601541561105e565b9050611050565b7ffc9be71c000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f80fd5b3461122d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261122d5760e061126d61074a61127c565b61127a604051809261129f565bf35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361122d57565b6020809163ffffffff8151168452015191015f905b600282106112c157505050565b60206112fa600192855190604060609263ffffffff815116835267ffffffffffffffff6020820151166020840152015160408201520190565b9301910190916112b4565b6004359063ffffffff8216820361122d57565b9060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261122d5760043567ffffffffffffffff811161122d578260238201121561122d5780600401359267ffffffffffffffff841161122d5760248460051b8301011161122d576024019190565b6060810190811067ffffffffffffffff8211176113a657604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040810190811067ffffffffffffffff8211176113a657604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113a657604052565b60408051919061144081846113ef565b825f5b82811061144f57505050565b60209060405161145e8161138a565b5f81525f838201525f60408201528184015201611443565b60405190611483826113d3565b815f81526020611491611430565b910152565b90604051916114a4836113d3565b5f835b600282106114b457505050565b600260206001926040516114c78161138a565b67ffffffffffffffff875463ffffffff81168352841c16838201528487015460408201528152019301910190916114a7565b73ffffffffffffffffffffffffffffffffffffffff90611517611476565b5016805f52600160205263ffffffff60405f205416905f525f60205261154e60405f2060405192611547846113d3565b8352611496565b602082015290565b3d156115ae573d9067ffffffffffffffff82116113a657604051916115a360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601846113ef565b82523d5f602084013e565b606090565b91908110156111555760051b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361122d5790565b67ffffffffffffffff81116113a65760051b60200190565b80518210156111555760209160051b010190565b3563ffffffff8116810361122d5790565b9190820180921161162e57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffdfea2646970667358221220236b5fdac362bf9430c9284c4a3de2a26513c7a763b0498c5fd84d9e2de3781064736f6c634300081b0033