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
0x60a034606a57601f61171438819003918201601f19168301916001600160401b03831184841017606e57808492602094604052833981010312606a575163ffffffff81168103606a5760805260405161169190816100838239608051818181610ae80152610cd40152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040526004361015610011575f80fd5b5f5f3560e01c80630220168114611231578063184ba9a714610fe357806319447b5914610d915780631ab971ab14610c9457806334e80c3414610bd4578063430ae46914610b6f578063561aaa0314610b0c578063950e75f414610aad57806397c59b9f14610a155780639e03d01e1461092c578063aa38319a14610856578063b68f68bc14610782578063d44af25614610677578063dcb67dc51461060e578063e5497c86146102095763fa352c00146100ca575f80fd5b346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff61011661127c565b16808252600360205273ffffffffffffffffffffffffffffffffffffffff60408320541633036101a8578082526003602052604082207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558082526004602052816040812055337f76e6646868d096078ac7f3f1401c3aaa55dc84890ec74b99c699e4754714b18e8380a380f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6e6f742d6f776e657200000000000000000000000000000000000000000000006044820152fd5b80fd5b5060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065760043567ffffffffffffffff811161060a573660238201121561060a5780600401359067ffffffffffffffff8211610606573660246060840283010111610606576024358015158103610602573384526003602052604084205473ffffffffffffffffffffffffffffffffffffffff166105d95733915b8490855b8581101561051f57606081028201602481019373ffffffffffffffffffffffffffffffffffffffff6102e0866115c3565b16895260026020526040892073ffffffffffffffffffffffffffffffffffffffff88165f5260205260ff60405f2054165f146104e85788905b86604484019263ffffffff8061032e86611610565b92169116106104d7575063ffffffff61034683611610565b1690633b9aca00820291808304633b9aca0014901517156104aa57873461036d8484611621565b1161045e578b808080866103808d6115c3565b5af161038a611556565b501561042157509163ffffffff6103cc6103c66103c073ffffffffffffffffffffffffffffffffffffffff956001999897611621565b996115c3565b92611610565b6064604051950135855216602084015216907f6670e7276ccbaffc9cb8b4c6c02179e6d89aae16fe663927529a4db6cc013173604073ffffffffffffffffffffffffffffffffffffffff8a1692a35b016102af565b9350955050506104335760019061041b565b7f8fa810ca000000000000000000000000000000000000000000000000000000008752600452602486fd5b925095509150610471575060019061041b565b8761047e60449286611621565b7f7040b58c00000000000000000000000000000000000000000000000000000000825260045234602452fd5b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b92509450506104335760019061041b565b73ffffffffffffffffffffffffffffffffffffffff610506866115c3565b168952600160205263ffffffff60408a20541690610319565b868380341161052c575080f35b34033481116105ac578180808093335af1610545611556565b501561054e5780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f726566756e642d6661696c0000000000000000000000000000000000000000006044820152fd5b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b338452600360205273ffffffffffffffffffffffffffffffffffffffff604085205416916102ab565b8380fd5b8280fd5b5080fd5b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065763ffffffff604060209273ffffffffffffffffffffffffffffffffffffffff61066561127c565b16815260018452205416604051908152f35b50346102065761068636611318565b90610690826115e4565b9161069e60405193846113ef565b8083527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06106cb826115e4565b01845b81811061076b575050835b818110610731578385604051918291602083016020845282518091526020604085019301915b81811061070d575050500390f35b91935091602060e082610723600194885161129f565b0194019101918493926106ff565b8061074f61074a61074560019486886115b3565b6115c3565b6114f9565b61075982876115fc565b5261076481866115fc565b50016106d9565b602090610776611476565b828288010152016106ce565b50346102065761079136611318565b825b81811061079e578380f35b60019033855260026020526040852073ffffffffffffffffffffffffffffffffffffffff6107d06107458487896115b3565b165f5260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00815416905573ffffffffffffffffffffffffffffffffffffffff6108236107458386886115b3565b166040518681527f0a0312df153a43bbacc69017600fd2d548d9f4529e7b80a0a5ec6ed89e2b287e60203392a301610793565b50346102065761086536611318565b825b818110610872578380f35b60019033855260026020526040852073ffffffffffffffffffffffffffffffffffffffff6108a46107458487896115b3565b165f5260205260405f20827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff6108f96107458386886115b3565b166040518381527f0a0312df153a43bbacc69017600fd2d548d9f4529e7b80a0a5ec6ed89e2b287e60203392a301610867565b503461020657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657338152600360205273ffffffffffffffffffffffffffffffffffffffff60408220541680156109ed573382526003602052604082207fffffffffffffffffffffffff00000000000000000000000000000000000000008154169055338252600460205281604081205533907f76e6646868d096078ac7f3f1401c3aaa55dc84890ec74b99c699e4754714b18e8380a380f35b6004827fa0ada974000000000000000000000000000000000000000000000000000000008152fd5b50346102065760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610a4d61127c565b906024359173ffffffffffffffffffffffffffffffffffffffff8316830361060a5773ffffffffffffffffffffffffffffffffffffffff918260409216815260026020522091165f52602052602060ff60405f2054166040519015158152f35b503461020657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657602060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657604060209173ffffffffffffffffffffffffffffffffffffffff610b5e61127c565b168152600483522054604051908152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff604060209282610bc261127c565b16815260038452205416604051908152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff610c2161127c565b610c29611430565b5016815280602052610c3d60408220611496565b60405191825b60028210610c505760c084f35b6020610c89600192855190604060609263ffffffff815116835267ffffffffffffffff6020820151166020840152015160408201520190565b930191019091610c43565b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610ccc611305565b63ffffffff807f000000000000000000000000000000000000000000000000000000000000000016911690808211610d625750338252600160205260408220817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008254161790556040519081527fb3d0d1c9055b5559806e0c3b8634f9bea1690bd00116173edd11aa20ac9ef09460203392a280f35b82917ff6afaf9d0000000000000000000000000000000000000000000000000000000060449452600452602452fd5b5060a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610dc461127c565b906024359160443560ff81168091036106065773ffffffffffffffffffffffffffffffffffffffff8216908115610fbb57836080602092604051848101907f686565642e64656c65676174652e763100000000000000000000000000000000825246604082015230606082015233848201528660a08201528960c082015260c08152610e5160e0826113ef565b51902090604051918252848201526064356040820152608435606082015282805260015afa15610fb0578073ffffffffffffffffffffffffffffffffffffffff84511603610f88578293818452600360205260408420337fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905581845260046020528060408520556040519081527f2b567f02d0528bcc32125a590269fabe81d4ca2e26e34e07a49774f9f065efcd60203392a334610f115750f35b8180809234905af1610f21611556565b5015610f2a5780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f66756e642d6661696c00000000000000000000000000000000000000000000006044820152fd5b6004837ffdf4e6f9000000000000000000000000000000000000000000000000000000008152fd5b6040513d84823e3d90fd5b6004847ffdf4e6f9000000000000000000000000000000000000000000000000000000008152fd5b3461122d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261122d5761101a611305565b602435801561120557335f525f60205260405f209163ffffffff83541663ffffffff6002850154169081811191825f146111fe57505b6001850154159081806111f2575b15806111dc575b6111a457501561118257505f5b63ffffffff604051926110848461138a565b16938483526020830167ffffffffffffffff42168152604084019185835260028410156111555763ffffffff8091600195861b01955116167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000855416178455517fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff6bffffffffffffffff0000000085549260201b1691161783555191015560405191825260208201527fdd57986ec96d909dc3ef348b416fe63afd6585502597be317db0bb1d5b7c366360403392a2005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b600384015461119357506001611072565b61119d575f611072565b6001611072565b63ffffffff9081857fe6c06aa1000000000000000000000000000000000000000000000000000000005f52166004521660245260445ffd5b5063ffffffff811663ffffffff85161115611065565b5060038601541561105e565b9050611050565b7ffc9be71c000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f80fd5b3461122d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261122d5760e061126d61074a61127c565b61127a604051809261129f565bf35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361122d57565b6020809163ffffffff8151168452015191015f905b600282106112c157505050565b60206112fa600192855190604060609263ffffffff815116835267ffffffffffffffff6020820151166020840152015160408201520190565b9301910190916112b4565b6004359063ffffffff8216820361122d57565b9060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261122d5760043567ffffffffffffffff811161122d578260238201121561122d5780600401359267ffffffffffffffff841161122d5760248460051b8301011161122d576024019190565b6060810190811067ffffffffffffffff8211176113a657604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040810190811067ffffffffffffffff8211176113a657604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113a657604052565b60408051919061144081846113ef565b825f5b82811061144f57505050565b60209060405161145e8161138a565b5f81525f838201525f60408201528184015201611443565b60405190611483826113d3565b815f81526020611491611430565b910152565b90604051916114a4836113d3565b5f835b600282106114b457505050565b600260206001926040516114c78161138a565b67ffffffffffffffff875463ffffffff81168352841c16838201528487015460408201528152019301910190916114a7565b73ffffffffffffffffffffffffffffffffffffffff90611517611476565b5016805f52600160205263ffffffff60405f205416905f525f60205261154e60405f2060405192611547846113d3565b8352611496565b602082015290565b3d156115ae573d9067ffffffffffffffff82116113a657604051916115a360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601846113ef565b82523d5f602084013e565b606090565b91908110156111555760051b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361122d5790565b67ffffffffffffffff81116113a65760051b60200190565b80518210156111555760209160051b010190565b3563ffffffff8116810361122d5790565b9190820180921161162e57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffdfea2646970667358221220236b5fdac362bf9430c9284c4a3de2a26513c7a763b0498c5fd84d9e2de3781064736f6c634300081b00330000000000000000000000000000000000000000000000000000000000989680
Deployed ByteCode
0x60806040526004361015610011575f80fd5b5f5f3560e01c80630220168114611231578063184ba9a714610fe357806319447b5914610d915780631ab971ab14610c9457806334e80c3414610bd4578063430ae46914610b6f578063561aaa0314610b0c578063950e75f414610aad57806397c59b9f14610a155780639e03d01e1461092c578063aa38319a14610856578063b68f68bc14610782578063d44af25614610677578063dcb67dc51461060e578063e5497c86146102095763fa352c00146100ca575f80fd5b346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff61011661127c565b16808252600360205273ffffffffffffffffffffffffffffffffffffffff60408320541633036101a8578082526003602052604082207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558082526004602052816040812055337f76e6646868d096078ac7f3f1401c3aaa55dc84890ec74b99c699e4754714b18e8380a380f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6e6f742d6f776e657200000000000000000000000000000000000000000000006044820152fd5b80fd5b5060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065760043567ffffffffffffffff811161060a573660238201121561060a5780600401359067ffffffffffffffff8211610606573660246060840283010111610606576024358015158103610602573384526003602052604084205473ffffffffffffffffffffffffffffffffffffffff166105d95733915b8490855b8581101561051f57606081028201602481019373ffffffffffffffffffffffffffffffffffffffff6102e0866115c3565b16895260026020526040892073ffffffffffffffffffffffffffffffffffffffff88165f5260205260ff60405f2054165f146104e85788905b86604484019263ffffffff8061032e86611610565b92169116106104d7575063ffffffff61034683611610565b1690633b9aca00820291808304633b9aca0014901517156104aa57873461036d8484611621565b1161045e578b808080866103808d6115c3565b5af161038a611556565b501561042157509163ffffffff6103cc6103c66103c073ffffffffffffffffffffffffffffffffffffffff956001999897611621565b996115c3565b92611610565b6064604051950135855216602084015216907f6670e7276ccbaffc9cb8b4c6c02179e6d89aae16fe663927529a4db6cc013173604073ffffffffffffffffffffffffffffffffffffffff8a1692a35b016102af565b9350955050506104335760019061041b565b7f8fa810ca000000000000000000000000000000000000000000000000000000008752600452602486fd5b925095509150610471575060019061041b565b8761047e60449286611621565b7f7040b58c00000000000000000000000000000000000000000000000000000000825260045234602452fd5b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b92509450506104335760019061041b565b73ffffffffffffffffffffffffffffffffffffffff610506866115c3565b168952600160205263ffffffff60408a20541690610319565b868380341161052c575080f35b34033481116105ac578180808093335af1610545611556565b501561054e5780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f726566756e642d6661696c0000000000000000000000000000000000000000006044820152fd5b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b338452600360205273ffffffffffffffffffffffffffffffffffffffff604085205416916102ab565b8380fd5b8280fd5b5080fd5b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065763ffffffff604060209273ffffffffffffffffffffffffffffffffffffffff61066561127c565b16815260018452205416604051908152f35b50346102065761068636611318565b90610690826115e4565b9161069e60405193846113ef565b8083527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06106cb826115e4565b01845b81811061076b575050835b818110610731578385604051918291602083016020845282518091526020604085019301915b81811061070d575050500390f35b91935091602060e082610723600194885161129f565b0194019101918493926106ff565b8061074f61074a61074560019486886115b3565b6115c3565b6114f9565b61075982876115fc565b5261076481866115fc565b50016106d9565b602090610776611476565b828288010152016106ce565b50346102065761079136611318565b825b81811061079e578380f35b60019033855260026020526040852073ffffffffffffffffffffffffffffffffffffffff6107d06107458487896115b3565b165f5260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00815416905573ffffffffffffffffffffffffffffffffffffffff6108236107458386886115b3565b166040518681527f0a0312df153a43bbacc69017600fd2d548d9f4529e7b80a0a5ec6ed89e2b287e60203392a301610793565b50346102065761086536611318565b825b818110610872578380f35b60019033855260026020526040852073ffffffffffffffffffffffffffffffffffffffff6108a46107458487896115b3565b165f5260205260405f20827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff6108f96107458386886115b3565b166040518381527f0a0312df153a43bbacc69017600fd2d548d9f4529e7b80a0a5ec6ed89e2b287e60203392a301610867565b503461020657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657338152600360205273ffffffffffffffffffffffffffffffffffffffff60408220541680156109ed573382526003602052604082207fffffffffffffffffffffffff00000000000000000000000000000000000000008154169055338252600460205281604081205533907f76e6646868d096078ac7f3f1401c3aaa55dc84890ec74b99c699e4754714b18e8380a380f35b6004827fa0ada974000000000000000000000000000000000000000000000000000000008152fd5b50346102065760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610a4d61127c565b906024359173ffffffffffffffffffffffffffffffffffffffff8316830361060a5773ffffffffffffffffffffffffffffffffffffffff918260409216815260026020522091165f52602052602060ff60405f2054166040519015158152f35b503461020657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657602060405163ffffffff7f0000000000000000000000000000000000000000000000000000000000989680168152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657604060209173ffffffffffffffffffffffffffffffffffffffff610b5e61127c565b168152600483522054604051908152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff604060209282610bc261127c565b16815260038452205416604051908152f35b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102065773ffffffffffffffffffffffffffffffffffffffff610c2161127c565b610c29611430565b5016815280602052610c3d60408220611496565b60405191825b60028210610c505760c084f35b6020610c89600192855190604060609263ffffffff815116835267ffffffffffffffff6020820151166020840152015160408201520190565b930191019091610c43565b50346102065760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610ccc611305565b63ffffffff807f000000000000000000000000000000000000000000000000000000000098968016911690808211610d625750338252600160205260408220817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008254161790556040519081527fb3d0d1c9055b5559806e0c3b8634f9bea1690bd00116173edd11aa20ac9ef09460203392a280f35b82917ff6afaf9d0000000000000000000000000000000000000000000000000000000060449452600452602452fd5b5060a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261020657610dc461127c565b906024359160443560ff81168091036106065773ffffffffffffffffffffffffffffffffffffffff8216908115610fbb57836080602092604051848101907f686565642e64656c65676174652e763100000000000000000000000000000000825246604082015230606082015233848201528660a08201528960c082015260c08152610e5160e0826113ef565b51902090604051918252848201526064356040820152608435606082015282805260015afa15610fb0578073ffffffffffffffffffffffffffffffffffffffff84511603610f88578293818452600360205260408420337fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905581845260046020528060408520556040519081527f2b567f02d0528bcc32125a590269fabe81d4ca2e26e34e07a49774f9f065efcd60203392a334610f115750f35b8180809234905af1610f21611556565b5015610f2a5780f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f66756e642d6661696c00000000000000000000000000000000000000000000006044820152fd5b6004837ffdf4e6f9000000000000000000000000000000000000000000000000000000008152fd5b6040513d84823e3d90fd5b6004847ffdf4e6f9000000000000000000000000000000000000000000000000000000008152fd5b3461122d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261122d5761101a611305565b602435801561120557335f525f60205260405f209163ffffffff83541663ffffffff6002850154169081811191825f146111fe57505b6001850154159081806111f2575b15806111dc575b6111a457501561118257505f5b63ffffffff604051926110848461138a565b16938483526020830167ffffffffffffffff42168152604084019185835260028410156111555763ffffffff8091600195861b01955116167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000855416178455517fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff6bffffffffffffffff0000000085549260201b1691161783555191015560405191825260208201527fdd57986ec96d909dc3ef348b416fe63afd6585502597be317db0bb1d5b7c366360403392a2005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b600384015461119357506001611072565b61119d575f611072565b6001611072565b63ffffffff9081857fe6c06aa1000000000000000000000000000000000000000000000000000000005f52166004521660245260445ffd5b5063ffffffff811663ffffffff85161115611065565b5060038601541561105e565b9050611050565b7ffc9be71c000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f80fd5b3461122d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261122d5760e061126d61074a61127c565b61127a604051809261129f565bf35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361122d57565b6020809163ffffffff8151168452015191015f905b600282106112c157505050565b60206112fa600192855190604060609263ffffffff815116835267ffffffffffffffff6020820151166020840152015160408201520190565b9301910190916112b4565b6004359063ffffffff8216820361122d57565b9060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261122d5760043567ffffffffffffffff811161122d578260238201121561122d5780600401359267ffffffffffffffff841161122d5760248460051b8301011161122d576024019190565b6060810190811067ffffffffffffffff8211176113a657604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040810190811067ffffffffffffffff8211176113a657604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113a657604052565b60408051919061144081846113ef565b825f5b82811061144f57505050565b60209060405161145e8161138a565b5f81525f838201525f60408201528184015201611443565b60405190611483826113d3565b815f81526020611491611430565b910152565b90604051916114a4836113d3565b5f835b600282106114b457505050565b600260206001926040516114c78161138a565b67ffffffffffffffff875463ffffffff81168352841c16838201528487015460408201528152019301910190916114a7565b73ffffffffffffffffffffffffffffffffffffffff90611517611476565b5016805f52600160205263ffffffff60405f205416905f525f60205261154e60405f2060405192611547846113d3565b8352611496565b602082015290565b3d156115ae573d9067ffffffffffffffff82116113a657604051916115a360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601846113ef565b82523d5f602084013e565b606090565b91908110156111555760051b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361122d5790565b67ffffffffffffffff81116113a65760051b60200190565b80518210156111555760209160051b010190565b3563ffffffff8116810361122d5790565b9190820180921161162e57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffdfea2646970667358221220236b5fdac362bf9430c9284c4a3de2a26513c7a763b0498c5fd84d9e2de3781064736f6c634300081b0033