ETH Price: $2,386.80 (-4.15%)
 

Overview

ETH Balance

13.49799349523143895 ETH

Eth Value

$32,217.04 (@ $2,386.80/ETH)

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Batch Claim224730382025-05-13 8:12:475 days ago1747123967IN
0x1CA2007a...810896454
0 ETH0.000189952.17435879
Batch Claim223821962025-04-30 13:35:4718 days ago1746020147IN
0x1CA2007a...810896454
0 ETH0.000201522.30683926
Batch Claim222407992025-04-10 20:04:2338 days ago1744315463IN
0x1CA2007a...810896454
0 ETH0.000170291.38039959
Batch Claim219284402025-02-26 5:33:2381 days ago1740548003IN
0x1CA2007a...810896454
0 ETH0.000146621.188413
Batch Claim216502202025-01-18 8:37:35120 days ago1737189455IN
0x1CA2007a...810896454
0 ETH0.0010772812.33448248
Batch Claim216039042025-01-11 21:23:59126 days ago1736630639IN
0x1CA2007a...810896454
0 ETH0.000538036.15873217
Batch Claim215505582025-01-04 10:36:47134 days ago1735987007IN
0x1CA2007a...810896454
0 ETH0.000720015.83652778
Batch Claim214809742024-12-25 17:26:59144 days ago1735147619IN
0x1CA2007a...810896454
0 ETH0.000847656.87123605
Batch Claim214788962024-12-25 10:29:11144 days ago1735122551IN
0x1CA2007a...810896454
0 ETH0.000584836.69444951
Batch Claim214779572024-12-25 7:20:47144 days ago1735111247IN
0x1CA2007a...810896454
0 ETH0.000522294.23377065
Batch Claim214744302024-12-24 19:31:23145 days ago1735068683IN
0x1CA2007a...810896454
0 ETH0.000841846.82410188
Batch Claim214701122024-12-24 5:01:47145 days ago1735016507IN
0x1CA2007a...810896454
0 ETH0.0004933.99637679
Batch Claim214696912024-12-24 3:36:35145 days ago1735011395IN
0x1CA2007a...810896454
0 ETH0.000616835.00020018
Batch Claim214660672024-12-23 15:25:47146 days ago1734967547IN
0x1CA2007a...810896454
0 ETH0.0026770521.70066121
Batch Claim214650052024-12-23 11:51:47146 days ago1734954707IN
0x1CA2007a...810896454
0 ETH0.000708955.7469335
Batch Claim214636982024-12-23 7:28:23146 days ago1734938903IN
0x1CA2007a...810896454
0 ETH0.000503035.75816925
Batch Claim214636702024-12-23 7:22:35146 days ago1734938555IN
0x1CA2007a...810896454
0 ETH0.000436314.99440662
Batch Claim214636652024-12-23 7:21:35146 days ago1734938495IN
0x1CA2007a...810896454
0 ETH0.000437665.00984851
Batch Claim214636472024-12-23 7:17:59146 days ago1734938279IN
0x1CA2007a...810896454
0 ETH0.00041374.73563348
Batch Claim214635352024-12-23 6:55:35146 days ago1734936935IN
0x1CA2007a...810896454
0 ETH0.00039764.55134179
Batch Claim214635152024-12-23 6:51:35146 days ago1734936695IN
0x1CA2007a...810896454
0 ETH0.000391544.48186769
Batch Claim214634852024-12-23 6:45:35146 days ago1734936335IN
0x1CA2007a...810896454
0 ETH0.000456885.22988682
Batch Claim214634772024-12-23 6:43:59146 days ago1734936239IN
0x1CA2007a...810896454
0 ETH0.000435974.99046951
Batch Claim214633812024-12-23 6:24:35146 days ago1734935075IN
0x1CA2007a...810896454
0 ETH0.000396044.53339071
Batch Claim214633752024-12-23 6:23:23146 days ago1734935003IN
0x1CA2007a...810896454
0 ETH0.000414564.7460858
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer224730382025-05-13 8:12:475 days ago1747123967
0x1CA2007a...810896454
0.01159554 ETH
Transfer223821962025-04-30 13:35:4718 days ago1746020147
0x1CA2007a...810896454
0.02212427 ETH
Transfer216502202025-01-18 8:37:35120 days ago1737189455
0x1CA2007a...810896454
0.01179457 ETH
Transfer216039042025-01-11 21:23:59126 days ago1736630639
0x1CA2007a...810896454
0.03986408 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00156702 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.0048369 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00703 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.0013275 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.0180375 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00809375 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00151425 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.06475 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00203752 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.023125 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.004375 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00211615 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00232598 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00153318 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.02335625 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00809375 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00330125 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.003515 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.0115625 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.00265507 ETH
Transfer215972092025-01-10 22:57:23127 days ago1736549843
0x1CA2007a...810896454
0.009361 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TokenDistributor

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

import "../globals/IGlobals.sol";
import "../globals/LibGlobals.sol";
import "../tokens/IERC20.sol";
import "../utils/LibAddress.sol";
import "../utils/LibERC20Compat.sol";
import "../utils/LibRawResult.sol";
import "../utils/LibSafeCast.sol";

import "./ITokenDistributor.sol";

/// @notice Creates token distributions for parties (or any contract that
///         implements `ITokenDistributorParty`).
contract TokenDistributor is ITokenDistributor {
    using LibAddress for address payable;
    using LibERC20Compat for IERC20;
    using LibRawResult for bytes;
    using LibSafeCast for uint256;

    struct DistributionState {
        // The hash of the `DistributionInfo`.
        bytes32 distributionHash;
        // The remaining member supply.
        uint128 remainingMemberSupply;
        // Whether the distribution's feeRecipient has claimed its fee.
        bool wasFeeClaimed;
        // Whether a governance token has claimed its distribution share.
        mapping(uint256 => bool) hasPartyTokenClaimed;
    }

    // Arguments for `_createDistribution()`.
    struct CreateDistributionArgs {
        ITokenDistributorParty party;
        TokenType tokenType;
        address token;
        uint256 currentTokenBalance;
        address payable feeRecipient;
        uint16 feeBps;
    }

    event EmergencyExecute(address target, bytes data);

    error OnlyPartyDaoError(address notDao, address partyDao);
    error InvalidDistributionInfoError(DistributionInfo info);
    error DistributionAlreadyClaimedByPartyTokenError(uint256 distributionId, uint256 partyTokenId);
    error DistributionFeeAlreadyClaimedError(uint256 distributionId);
    error MustOwnTokenError(address sender, address expectedOwner, uint256 partyTokenId);
    error EmergencyActionsNotAllowedError();
    error InvalidDistributionSupplyError(uint128 supply);
    error OnlyFeeRecipientError(address caller, address feeRecipient);
    error InvalidFeeBpsError(uint16 feeBps);

    // Token address used to indicate a native distribution (i.e. distribution of ETH).
    address private constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    /// @notice The `Globals` contract storing global configuration values. This contract
    ///         is immutable and it’s address will never change.
    IGlobals public immutable GLOBALS;
    /// @notice Timestamp when the DAO is no longer allowed to call emergency functions.
    uint40 public immutable EMERGENCY_DISABLED_TIMESTAMP;

    /// @notice Last distribution ID for a party.
    mapping(ITokenDistributorParty => uint256) public lastDistributionIdPerParty;
    /// Last known balance of a token, identified by an ID derived from the token.
    /// Gets lazily updated when creating and claiming a distribution (transfers).
    /// Allows one to simply transfer and call `createDistribution()` without
    /// fussing with allowances.
    mapping(bytes32 => uint256) private _storedBalances;
    // tokenDistributorParty => distributionId => DistributionState
    mapping(ITokenDistributorParty => mapping(uint256 => DistributionState)) private _distributionStates;

    // msg.sender == DAO
    modifier onlyPartyDao() {
        {
            address partyDao = GLOBALS.getAddress(LibGlobals.GLOBAL_DAO_WALLET);
            if (msg.sender != partyDao) {
                revert OnlyPartyDaoError(msg.sender, partyDao);
            }
        }
        _;
    }

    // emergencyActionsDisabled == false
    modifier onlyIfEmergencyActionsAllowed() {
        if (block.timestamp > EMERGENCY_DISABLED_TIMESTAMP) {
            revert EmergencyActionsNotAllowedError();
        }
        _;
    }

    // Set the `Globals` contract.
    constructor(IGlobals globals, uint40 emergencyDisabledTimestamp) {
        GLOBALS = globals;
        EMERGENCY_DISABLED_TIMESTAMP = emergencyDisabledTimestamp;
    }

    /// @inheritdoc ITokenDistributor
    function createNativeDistribution(
        ITokenDistributorParty party,
        address payable feeRecipient,
        uint16 feeBps
    )
        external
        payable
        returns (DistributionInfo memory info)
    {
        info = _createDistribution(CreateDistributionArgs({
            party: party,
            tokenType: TokenType.Native,
            token: NATIVE_TOKEN_ADDRESS,
            currentTokenBalance: address(this).balance,
            feeRecipient: feeRecipient,
            feeBps: feeBps
        }));
    }

    /// @inheritdoc ITokenDistributor
    function createErc20Distribution(
        IERC20 token,
        ITokenDistributorParty party,
        address payable feeRecipient,
        uint16 feeBps
    )
        external
        returns (DistributionInfo memory info)
    {
        info = _createDistribution(CreateDistributionArgs({
            party: party,
            tokenType: TokenType.Erc20,
            token: address(token),
            currentTokenBalance: token.balanceOf(address(this)),
            feeRecipient: feeRecipient,
            feeBps: feeBps
        }));
    }

    /// @inheritdoc ITokenDistributor
    function claim(DistributionInfo calldata info, uint256 partyTokenId)
        public
        returns (uint128 amountClaimed)
    {
        // Caller must own the party token.
        {
            address ownerOfPartyToken = info.party.ownerOf(partyTokenId);
            if (msg.sender != ownerOfPartyToken) {
                revert MustOwnTokenError(msg.sender, ownerOfPartyToken, partyTokenId);
            }
        }
        // DistributionInfo must be correct for this distribution ID.
        DistributionState storage state = _distributionStates[info.party][info.distributionId];
        if (state.distributionHash != _getDistributionHash(info)) {
            revert InvalidDistributionInfoError(info);
        }
        // The partyTokenId must not have claimed its distribution yet.
        if (state.hasPartyTokenClaimed[partyTokenId]) {
            revert DistributionAlreadyClaimedByPartyTokenError(info.distributionId, partyTokenId);
        }
        // Mark the partyTokenId as having claimed their distribution.
        state.hasPartyTokenClaimed[partyTokenId] = true;

        // Compute amount owed to partyTokenId.
        amountClaimed = getClaimAmount(info.party, info.memberSupply, partyTokenId);

        // Cap at the remaining member supply. Otherwise a malicious
        // party could drain more than the distribution supply.
        uint128 remainingMemberSupply = state.remainingMemberSupply;
        amountClaimed = amountClaimed > remainingMemberSupply
            ? remainingMemberSupply
            : amountClaimed;
        state.remainingMemberSupply = remainingMemberSupply - amountClaimed;

        // Transfer tokens owed.
        _transfer(
            info.tokenType,
            info.token,
            payable(msg.sender),
            amountClaimed
        );
        emit DistributionClaimedByPartyToken(
            info.party,
            partyTokenId,
            msg.sender,
            info.tokenType,
            info.token,
            amountClaimed
        );
    }

    /// @inheritdoc ITokenDistributor
    function claimFee(DistributionInfo calldata info, address payable recipient)
        public
    {
        // DistributionInfo must be correct for this distribution ID.
        DistributionState storage state = _distributionStates[info.party][info.distributionId];
        if (state.distributionHash != _getDistributionHash(info)) {
            revert InvalidDistributionInfoError(info);
        }
        // Caller must be the fee recipient.
        if (info.feeRecipient != msg.sender) {
            revert OnlyFeeRecipientError(msg.sender, info.feeRecipient);
        }
        // Must not have claimed the fee yet.
        if (state.wasFeeClaimed) {
            revert DistributionFeeAlreadyClaimedError(info.distributionId);
        }
        // Mark the fee as claimed.
        state.wasFeeClaimed = true;
        // Transfer the tokens owed.
        _transfer(
            info.tokenType,
            info.token,
            recipient,
            info.fee
        );
        emit DistributionFeeClaimed(
            info.party,
            info.feeRecipient,
            info.tokenType,
            info.token,
            info.fee
        );
    }

    /// @inheritdoc ITokenDistributor
    function batchClaim(DistributionInfo[] calldata infos, uint256[] calldata partyTokenIds)
        external
        returns (uint128[] memory amountsClaimed)
    {
        amountsClaimed = new uint128[](infos.length);
        for (uint256 i = 0; i < infos.length; ++i) {
            amountsClaimed[i] = claim(infos[i], partyTokenIds[i]);
        }
    }

    /// @inheritdoc ITokenDistributor
    function batchClaimFee(DistributionInfo[] calldata infos, address payable[] calldata recipients)
        external
    {
        for (uint256 i = 0; i < infos.length; ++i) {
            claimFee(infos[i], recipients[i]);
        }
    }

    /// @inheritdoc ITokenDistributor
    function getClaimAmount(
        ITokenDistributorParty party,
        uint256 memberSupply,
        uint256 partyTokenId
    )
        public
        view
        returns (uint128)
    {
        // getDistributionShareOf() is the fraction of the memberSupply partyTokenId
        // is entitled to, scaled by 1e18.
        // We round up here to prevent dust amounts getting trapped in this contract.
        return (
            (
                uint256(party.getDistributionShareOf(partyTokenId))
                * memberSupply
                + (1e18 - 1)
            )
            / 1e18
        ).safeCastUint256ToUint128();
    }

    /// @inheritdoc ITokenDistributor
    function wasFeeClaimed(ITokenDistributorParty party, uint256 distributionId)
        external
        view
        returns (bool)
    {
        return _distributionStates[party][distributionId].wasFeeClaimed;
    }

    /// @inheritdoc ITokenDistributor
    function hasPartyTokenIdClaimed(
        ITokenDistributorParty party,
        uint256 partyTokenId,
        uint256 distributionId
    )
        external
        view returns (bool)
    {
        return _distributionStates[party][distributionId].hasPartyTokenClaimed[partyTokenId];
    }

    /// @inheritdoc ITokenDistributor
    function getRemainingMemberSupply(
        ITokenDistributorParty party,
        uint256 distributionId
    )
        external
        view
        returns (uint128)
    {
        return _distributionStates[party][distributionId].remainingMemberSupply;
    }

    /// @notice As the DAO, execute an arbitrary delegatecall from this contract.
    /// @dev Emergency actions must not be revoked for this to work.
    /// @param targetAddress The contract to delegatecall into.
    /// @param targetCallData The data to pass to the call.
    function emergencyExecute(
        address targetAddress,
        bytes calldata targetCallData
    )
        external
        onlyPartyDao
        onlyIfEmergencyActionsAllowed
    {
        (bool success, bytes memory res) = targetAddress.delegatecall(targetCallData);
        if (!success) {
            res.rawRevert();
        }
        emit EmergencyExecute(targetAddress, targetCallData);
    }

    function _createDistribution(CreateDistributionArgs memory args)
        private
        returns (DistributionInfo memory info)
    {
        if (args.feeBps > 1e4) {
            revert InvalidFeeBpsError(args.feeBps);
        }
        uint128 supply;
        {
            bytes32 balanceId = _getBalanceId(args.tokenType, args.token);
            supply = (args.currentTokenBalance - _storedBalances[balanceId])
                .safeCastUint256ToUint128();
            // Supply must be nonzero.
            if (supply == 0) {
                revert InvalidDistributionSupplyError(supply);
            }
            // Update stored balance.
            _storedBalances[balanceId] = args.currentTokenBalance;
        }

        // Create a distribution.
        uint128 fee = supply * args.feeBps / 1e4;
        uint128 memberSupply = supply - fee;

        info = DistributionInfo({
            tokenType: args.tokenType,
            distributionId: ++lastDistributionIdPerParty[args.party],
            token: args.token,
            party: args.party,
            memberSupply: memberSupply,
            feeRecipient: args.feeRecipient,
            fee: fee
        });
        (
            _distributionStates[args.party][info.distributionId].distributionHash,
            _distributionStates[args.party][info.distributionId].remainingMemberSupply
        ) = (_getDistributionHash(info), memberSupply);
        emit DistributionCreated(args.party, info);
    }

    function _transfer(
        TokenType tokenType,
        address token,
        address payable recipient,
        uint256 amount
    )
        private
    {
        bytes32 balanceId = _getBalanceId(tokenType, token);
        // Reduce stored token balance.
        uint256 storedBalance = _storedBalances[balanceId] - amount;
        // Temporarily set to max as a reentrancy guard. An interesing attack
        // could occur if we didn't do this where an attacker could `claim()` and
        // reenter upon transfer (eg. in the `tokensToSend` hook of an ERC777) to
        // `createERC20Distribution()`. Since the `balanceOf(address(this))`
        // would not of been updated yet, the supply would be miscalculated and
        // the attacker would create a distribution that essentially steals from
        // the last distribution they were claiming from. Here, we prevent that
        // by causing an arithmetic underflow with the supply calculation if
        // this were to be attempted.
        _storedBalances[balanceId] = type(uint256).max;
        if (tokenType == TokenType.Native) {
            recipient.transferEth(amount);
        } else {
            assert(tokenType == TokenType.Erc20);
            IERC20(token).compatTransfer(recipient, amount);
        }
        _storedBalances[balanceId] = storedBalance;
    }

    function _getDistributionHash(DistributionInfo memory info)
        internal
        pure
        returns (bytes32 hash)
    {
        assembly {
            hash := keccak256(info, 0xe0)
        }
    }

    function _getBalanceId(TokenType tokenType, address token)
        private
        pure
        returns (bytes32 balanceId)
    {
        if (tokenType == TokenType.Native) {
            return bytes32(uint256(uint160(NATIVE_TOKEN_ADDRESS)));
        }
        assert(tokenType == TokenType.Erc20);
        return bytes32(uint256(uint160(token)));
    }
}

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

import "../tokens/IERC20.sol";

import "./ITokenDistributorParty.sol";

/// @notice Creates token distributions for parties.
interface ITokenDistributor {
    enum TokenType {
        Native,
        Erc20
    }

    // Info on a distribution, created by createDistribution().
    struct DistributionInfo {
        // Type of distribution/token.
        TokenType tokenType;
        // ID of the distribution. Assigned by createDistribution().
        uint256 distributionId;
        // The party whose members can claim the distribution.
        ITokenDistributorParty party;
        // Who can claim `fee`.
        address payable feeRecipient;
        // The token being distributed.
        address token;
        // Total amount of `token` that can be claimed by party members.
        uint128 memberSupply;
        // Amount of `token` to be redeemed by `feeRecipient`.
        uint128 fee;
    }

    event DistributionCreated(
        ITokenDistributorParty indexed party,
        DistributionInfo info
    );
    event DistributionFeeClaimed(
        ITokenDistributorParty indexed party,
        address indexed feeRecipient,
        TokenType tokenType,
        address token,
        uint256 amount
    );
    event DistributionClaimedByPartyToken(
        ITokenDistributorParty indexed party,
        uint256 indexed partyTokenId,
        address indexed owner,
        TokenType tokenType,
        address token,
        uint256 amountClaimed
    );

    /// @notice Create a new distribution for an outstanding native token balance
    ///         governed by a party.
    /// @dev Native tokens should be transferred directly into this contract
    ///      immediately prior (same tx) to calling `createDistribution()` or
    ///      attached to the call itself.
    /// @param party The party whose members can claim the distribution.
    /// @param feeRecipient Who can claim `fee`.
    /// @param feeBps Percentage (in bps) of the distribution `feeRecipient` receives.
    /// @return info Information on the created distribution.
    function createNativeDistribution(
        ITokenDistributorParty party,
        address payable feeRecipient,
        uint16 feeBps
    )
        external
        payable
        returns (DistributionInfo memory info);

    /// @notice Create a new distribution for an outstanding ERC20 token balance
    ///         governed by a party.
    /// @dev ERC20 tokens should be transferred directly into this contract
    ///      immediately prior (same tx) to calling `createDistribution()` or
    ///      attached to the call itself.
    /// @param token The ERC20 token to distribute.
    /// @param party The party whose members can claim the distribution.
    /// @param feeRecipient Who can claim `fee`.
    /// @param feeBps Percentage (in bps) of the distribution `feeRecipient` receives.
    /// @return info Information on the created distribution.
    function createErc20Distribution(
        IERC20 token,
        ITokenDistributorParty party,
        address payable feeRecipient,
        uint16 feeBps
    )
        external
        returns (DistributionInfo memory info);

    /// @notice Claim a portion of a distribution owed to a `partyTokenId` belonging
    ///         to the party that created the distribution. The caller
    ///         must own this token.
    /// @param info Information on the distribution being claimed.
    /// @param partyTokenId The ID of the party token to claim for.
    /// @return amountClaimed The amount of the distribution claimed.
    function claim(DistributionInfo calldata info, uint256 partyTokenId)
        external
        returns (uint128 amountClaimed);

    /// @notice Claim the fee for a distribution. Only a distribution's `feeRecipient`
    ///         can call this.
    /// @param info Information on the distribution being claimed.
    /// @param recipient The address to send the fee to.
    function claimFee(DistributionInfo calldata info, address payable recipient)
        external;

    /// @notice Batch version of `claim()`.
    /// @param infos Information on the distributions being claimed.
    /// @param partyTokenIds The ID of the party tokens to claim for.
    /// @return amountsClaimed The amount of the distributions claimed.
    function batchClaim(DistributionInfo[] calldata infos, uint256[] calldata partyTokenIds)
        external
        returns (uint128[] memory amountsClaimed);

    /// @notice Batch version of `claimFee()`.
    /// @param infos Information on the distributions to claim fees for.
    /// @param recipients The addresses to send the fees to.
    function batchClaimFee(DistributionInfo[] calldata infos, address payable[] calldata recipients)
        external;

    /// @notice Compute the amount of a distribution's token are owed to a party
    ///         member, identified by the `partyTokenId`.
    /// @param party The party to use for computing the claim amount.
    /// @param memberSupply Total amount of tokens that can be claimed in the distribution.
    /// @param partyTokenId The ID of the party token to claim for.
    /// @return claimAmount The amount of the distribution owed to the party member.
    function getClaimAmount(
        ITokenDistributorParty party,
        uint256 memberSupply,
        uint256 partyTokenId
    )
        external
        view
        returns (uint128);

    /// @notice Check whether the fee has been claimed for a distribution.
    /// @param party The party to use for checking whether the fee has been claimed.
    /// @param distributionId The ID of the distribution to check.
    /// @return feeClaimed Whether the fee has been claimed.
    function wasFeeClaimed(ITokenDistributorParty party, uint256 distributionId)
        external
        view
        returns (bool);

    /// @notice Check whether a `partyTokenId` has claimed their share of a distribution.
    /// @param party The party to use for checking whether the `partyTokenId` has claimed.
    /// @param partyTokenId The ID of the party token to check.
    /// @param distributionId The ID of the distribution to check.
    /// @return hasClaimed Whether the `partyTokenId` has claimed.
    function hasPartyTokenIdClaimed(
        ITokenDistributorParty party,
        uint256 partyTokenId,
        uint256 distributionId
    )
        external
        view returns (bool);

    /// @notice Get how much unclaimed member tokens are left in a distribution.
    /// @param party The party to use for checking the unclaimed member tokens.
    /// @param distributionId The ID of the distribution to check.
    /// @return remainingMemberSupply The amount of distribution supply remaining.
    function getRemainingMemberSupply(
        ITokenDistributorParty party,
        uint256 distributionId
    )
        external
        view
        returns (uint128);
}

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

// Interface the caller of `ITokenDistributor.createDistribution()` must implement.
interface ITokenDistributorParty {
    /// @notice Return the owner of a token.
    /// @param tokenId The token ID to query.
    /// @return owner The owner of `tokenId`.
    function ownerOf(uint256 tokenId) external view returns (address);
    /// @notice Return the distribution share of a token. Denominated fractions
    ///         of 1e18. I.e., 1e18 = 100%.
    /// @param tokenId The token ID to query.
    /// @return share The distribution percentage of `tokenId`.
    function getDistributionShareOf(uint256 tokenId) external view returns (uint256);
}

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

import "../utils/Implementation.sol";

// Single registry of global values controlled by multisig.
// See `LibGlobals` for all valid keys.
interface IGlobals {
    function getBytes32(uint256 key) external view returns (bytes32);
    function getUint256(uint256 key) external view returns (uint256);
    function getBool(uint256 key) external view returns (bool);
    function getAddress(uint256 key) external view returns (address);
    function getImplementation(uint256 key) external view returns (Implementation);
    function getIncludesBytes32(uint256 key, bytes32 value) external view returns (bool);
    function getIncludesUint256(uint256 key, uint256 value) external view returns (bool);
    function getIncludesAddress(uint256 key, address value) external view returns (bool);

    function setBytes32(uint256 key, bytes32 value) external;
    function setUint256(uint256 key, uint256 value) external;
    function setBool(uint256 key, bool value) external;
    function setAddress(uint256 key, address value) external;
    function setIncludesBytes32(uint256 key, bytes32 value, bool isIncluded) external;
    function setIncludesUint256(uint256 key, uint256 value, bool isIncluded) external;
    function setIncludesAddress(uint256 key, address value, bool isIncluded) external;
}

File 5 of 11 : LibGlobals.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

// Valid keys in `IGlobals`. Append-only.
library LibGlobals {
    uint256 internal constant GLOBAL_PARTY_IMPL                     = 1;
    uint256 internal constant GLOBAL_PROPOSAL_ENGINE_IMPL           = 2;
    uint256 internal constant GLOBAL_PARTY_FACTORY                  = 3;
    uint256 internal constant GLOBAL_GOVERNANCE_NFT_RENDER_IMPL     = 4;
    uint256 internal constant GLOBAL_CF_NFT_RENDER_IMPL             = 5;
    uint256 internal constant GLOBAL_OS_ZORA_AUCTION_TIMEOUT        = 6;
    uint256 internal constant GLOBAL_OS_ZORA_AUCTION_DURATION       = 7;
    uint256 internal constant GLOBAL_AUCTION_CF_IMPL                = 8;
    uint256 internal constant GLOBAL_BUY_CF_IMPL                    = 9;
    uint256 internal constant GLOBAL_COLLECTION_BUY_CF_IMPL         = 10;
    uint256 internal constant GLOBAL_DAO_WALLET                     = 11;
    uint256 internal constant GLOBAL_TOKEN_DISTRIBUTOR              = 12;
    uint256 internal constant GLOBAL_OPENSEA_CONDUIT_KEY            = 13;
    uint256 internal constant GLOBAL_OPENSEA_ZONE                   = 14;
    uint256 internal constant GLOBAL_PROPOSAL_MAX_CANCEL_DURATION   = 15;
    uint256 internal constant GLOBAL_ZORA_MIN_AUCTION_DURATION      = 16;
    uint256 internal constant GLOBAL_ZORA_MAX_AUCTION_DURATION      = 17;
    uint256 internal constant GLOBAL_ZORA_MAX_AUCTION_TIMEOUT       = 18;
    uint256 internal constant GLOBAL_OS_MIN_ORDER_DURATION          = 19;
    uint256 internal constant GLOBAL_OS_MAX_ORDER_DURATION          = 20;
    uint256 internal constant GLOBAL_DISABLE_PARTY_ACTIONS          = 21;
    uint256 internal constant GLOBAL_RENDERER_STORAGE               = 22;
    uint256 internal constant GLOBAL_PROPOSAL_MIN_CANCEL_DURATION   = 23;
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8;

// Minimal ERC20 interface.
interface IERC20 {
    event Transfer(address indexed owner, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 allowance);

    function transfer(address to, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 allowance) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function balanceOf(address owner) external view returns (uint256);
}

File 7 of 11 : Implementation.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

// Base contract for all contracts intended to be delegatecalled into.
abstract contract Implementation {
    error OnlyDelegateCallError();
    error OnlyConstructorError();

    address public immutable IMPL;

    constructor() { IMPL = address(this); }

    // Reverts if the current function context is not inside of a delegatecall.
    modifier onlyDelegateCall() virtual {
        if (address(this) == IMPL) {
            revert OnlyDelegateCallError();
        }
        _;
    }

    // Reverts if the current function context is not inside of a constructor.
    modifier onlyConstructor() {
        uint256 codeSize;
        assembly { codeSize := extcodesize(address()) }
        if (codeSize != 0) {
            revert OnlyConstructorError();
        }
        _;
    }
}

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

library LibAddress {
    error EthTransferFailed(address receiver, bytes errData);

    // Transfer ETH with full gas stipend.
    function transferEth(address payable receiver, uint256 amount)
        internal
    {
        if (amount == 0) return;

        (bool s, bytes memory r) = receiver.call{value: amount}("");
        if (!s) {
            revert EthTransferFailed(receiver, r);
        }
    }
}

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

import "../tokens/IERC20.sol";

// Compatibility helpers for ERC20s.
library LibERC20Compat {
    error NotATokenError(IERC20 token);
    error TokenTransferFailedError(IERC20 token, address to, uint256 amount);

    // Perform an `IERC20.transfer()` handling non-compliant implementations.
    function compatTransfer(IERC20 token, address to, uint256 amount)
        internal
    {
        (bool s, bytes memory r) =
            address(token).call(abi.encodeCall(IERC20.transfer, (to, amount)));
        if (s) {
            if (r.length == 0) {
                uint256 cs;
                assembly { cs := extcodesize(token) }
                if (cs == 0) {
                    revert NotATokenError(token);
                }
                return;
            }
            if (abi.decode(r, (bool))) {
                return;
            }
        }
        revert TokenTransferFailedError(token, to, amount);
    }
}

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

library LibRawResult {
    // Revert with the data in `b`.
    function rawRevert(bytes memory b)
        internal
        pure
    {
        assembly { revert(add(b, 32), mload(b)) }
    }

    // Return with the data in `b`.
    function rawReturn(bytes memory b)
        internal
        pure
    {
        assembly { return(add(b, 32), mload(b)) }
    }
}

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

library LibSafeCast {
    error Uint256ToUint96CastOutOfRange(uint256 v);
    error Uint256ToInt192CastOutOfRange(uint256 v);
    error Int192ToUint96CastOutOfRange(int192 i192);
    error Uint256ToInt128CastOutOfRangeError(uint256 u256);
    error Uint256ToUint128CastOutOfRangeError(uint256 u256);
    error Uint256ToUint40CastOutOfRangeError(uint256 u256);

    function safeCastUint256ToUint96(uint256 v) internal pure returns (uint96) {
        if (v > uint256(type(uint96).max)) {
            revert Uint256ToUint96CastOutOfRange(v);
        }
        return uint96(v);
    }

    function safeCastUint256ToUint128(uint256 v) internal pure returns (uint128) {
        if (v > uint256(type(uint128).max)) {
            revert Uint256ToUint128CastOutOfRangeError(v);
        }
        return uint128(v);
    }

    function safeCastUint256ToInt192(uint256 v) internal pure returns (int192) {
        if (v > uint256(uint192(type(int192).max))) {
            revert Uint256ToInt192CastOutOfRange(v);
        }
        return int192(uint192(v));
    }

    function safeCastUint96ToInt192(uint96 v) internal pure returns (int192) {
        return int192(uint192(v));
    }

    function safeCastInt192ToUint96(int192 i192) internal pure returns (uint96) {
        if (i192 < 0 || i192 > int192(uint192(type(uint96).max))) {
            revert Int192ToUint96CastOutOfRange(i192);
        }
        return uint96(uint192(i192));
    }

    function safeCastUint256ToInt128(uint256 x)
        internal
        pure
        returns (int128)
    {
        if (x > uint256(uint128(type(int128).max))) {
            revert Uint256ToInt128CastOutOfRangeError(x);
        }
        return int128(uint128(x));
    }

    function safeCastUint256ToUint40(uint256 x)
        internal
        pure
        returns (uint40)
    {
        if (x > uint256(type(uint40).max)) {
            revert Uint256ToUint40CastOutOfRangeError(x);
        }
        return uint40(x);
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/solmate/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin/=lib/openzeppelin-contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IGlobals","name":"globals","type":"address"},{"internalType":"uint40","name":"emergencyDisabledTimestamp","type":"uint40"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"uint256","name":"partyTokenId","type":"uint256"}],"name":"DistributionAlreadyClaimedByPartyTokenError","type":"error"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"}],"name":"DistributionFeeAlreadyClaimedError","type":"error"},{"inputs":[],"name":"EmergencyActionsNotAllowedError","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"errData","type":"bytes"}],"name":"EthTransferFailed","type":"error"},{"inputs":[{"components":[{"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"memberSupply","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct ITokenDistributor.DistributionInfo","name":"info","type":"tuple"}],"name":"InvalidDistributionInfoError","type":"error"},{"inputs":[{"internalType":"uint128","name":"supply","type":"uint128"}],"name":"InvalidDistributionSupplyError","type":"error"},{"inputs":[{"internalType":"uint16","name":"feeBps","type":"uint16"}],"name":"InvalidFeeBpsError","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"expectedOwner","type":"address"},{"internalType":"uint256","name":"partyTokenId","type":"uint256"}],"name":"MustOwnTokenError","type":"error"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"NotATokenError","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"feeRecipient","type":"address"}],"name":"OnlyFeeRecipientError","type":"error"},{"inputs":[{"internalType":"address","name":"notDao","type":"address"},{"internalType":"address","name":"partyDao","type":"address"}],"name":"OnlyPartyDaoError","type":"error"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenTransferFailedError","type":"error"},{"inputs":[{"internalType":"uint256","name":"u256","type":"uint256"}],"name":"Uint256ToUint128CastOutOfRangeError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"indexed":true,"internalType":"uint256","name":"partyTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountClaimed","type":"uint256"}],"name":"DistributionClaimedByPartyToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"components":[{"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"memberSupply","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"indexed":false,"internalType":"struct ITokenDistributor.DistributionInfo","name":"info","type":"tuple"}],"name":"DistributionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"indexed":true,"internalType":"address","name":"feeRecipient","type":"address"},{"indexed":false,"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DistributionFeeClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"EmergencyExecute","type":"event"},{"inputs":[],"name":"EMERGENCY_DISABLED_TIMESTAMP","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GLOBALS","outputs":[{"internalType":"contract IGlobals","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"memberSupply","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct ITokenDistributor.DistributionInfo[]","name":"infos","type":"tuple[]"},{"internalType":"uint256[]","name":"partyTokenIds","type":"uint256[]"}],"name":"batchClaim","outputs":[{"internalType":"uint128[]","name":"amountsClaimed","type":"uint128[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"memberSupply","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct ITokenDistributor.DistributionInfo[]","name":"infos","type":"tuple[]"},{"internalType":"address payable[]","name":"recipients","type":"address[]"}],"name":"batchClaimFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"memberSupply","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct ITokenDistributor.DistributionInfo","name":"info","type":"tuple"},{"internalType":"uint256","name":"partyTokenId","type":"uint256"}],"name":"claim","outputs":[{"internalType":"uint128","name":"amountClaimed","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"memberSupply","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct ITokenDistributor.DistributionInfo","name":"info","type":"tuple"},{"internalType":"address payable","name":"recipient","type":"address"}],"name":"claimFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"}],"name":"createErc20Distribution","outputs":[{"components":[{"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"memberSupply","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct ITokenDistributor.DistributionInfo","name":"info","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"uint16","name":"feeBps","type":"uint16"}],"name":"createNativeDistribution","outputs":[{"components":[{"internalType":"enum ITokenDistributor.TokenType","name":"tokenType","type":"uint8"},{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"address payable","name":"feeRecipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"memberSupply","type":"uint128"},{"internalType":"uint128","name":"fee","type":"uint128"}],"internalType":"struct ITokenDistributor.DistributionInfo","name":"info","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"bytes","name":"targetCallData","type":"bytes"}],"name":"emergencyExecute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"uint256","name":"memberSupply","type":"uint256"},{"internalType":"uint256","name":"partyTokenId","type":"uint256"}],"name":"getClaimAmount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"uint256","name":"distributionId","type":"uint256"}],"name":"getRemainingMemberSupply","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"uint256","name":"partyTokenId","type":"uint256"},{"internalType":"uint256","name":"distributionId","type":"uint256"}],"name":"hasPartyTokenIdClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ITokenDistributorParty","name":"","type":"address"}],"name":"lastDistributionIdPerParty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ITokenDistributorParty","name":"party","type":"address"},{"internalType":"uint256","name":"distributionId","type":"uint256"}],"name":"wasFeeClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60c060405234801561001057600080fd5b50604051611ce8380380611ce883398101604081905261002f9161004c565b6001600160a01b0390911660805264ffffffffff1660a05261009c565b6000806040838503121561005f57600080fd5b82516001600160a01b038116811461007657600080fd5b602084015190925064ffffffffff8116811461009157600080fd5b809150509250929050565b60805160a051611c1a6100ce6000396000818160f4015261085701526000818161016301526107a50152611c1a6000f3fe6080604052600436106100dd5760003560e01c8063a73bf89e1161007f578063e3a7ef5511610059578063e3a7ef55146102f1578063e81140ad14610342578063eedaf00d14610362578063ff7c0eea1461038257600080fd5b8063a73bf89e14610247578063bd71711114610267578063e0af030c146102a257600080fd5b806352800e82116100bb57806352800e821461019d57806357f72496146101d55780636984c669146101f7578063a0321a531461022757600080fd5b8063074ae6f1146100e25780633a32e54e14610131578063476f512514610151575b600080fd5b3480156100ee57600080fd5b506101167f000000000000000000000000000000000000000000000000000000000000000081565b60405164ffffffffff90911681526020015b60405180910390f35b61014461013f366004611362565b6103af565b60405161012891906113e1565b34801561015d57600080fd5b506101857f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610128565b3480156101a957600080fd5b506101bd6101b836600461146d565b610421565b6040516001600160801b039091168152602001610128565b3480156101e157600080fd5b506101f56101f036600461152a565b6106f0565b005b34801561020357600080fd5b50610217610212366004611596565b610754565b6040519015158152602001610128565b34801561023357600080fd5b506101f56102423660046115c2565b61078c565b34801561025357600080fd5b506101f5610262366004611647565b61094f565b34801561027357600080fd5b50610294610282366004611680565b60006020819052908152604090205481565b604051908152602001610128565b3480156102ae57600080fd5b506101bd6102bd366004611596565b6001600160a01b0391909116600090815260026020908152604080832093835292905220600101546001600160801b031690565b3480156102fd57600080fd5b5061021761030c3660046116a4565b6001600160a01b039290921660009081526002602081815260408084209584529481528483209383529201909152205460ff1690565b34801561034e57600080fd5b506101bd61035d3660046116a4565b610b42565b34801561036e57600080fd5b5061014461037d3660046116d9565b610beb565b34801561038e57600080fd5b506103a261039d36600461152a565b610ca8565b6040516101289190611733565b6103b76112ea565b6040805160c081019091526001600160a01b038516815261041990602081016000815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60208201524760408201526001600160a01b038616606082015261ffff8516608090910152610d76565b949350505050565b6000806104346060850160408601611680565b6001600160a01b0316636352211e846040518263ffffffff1660e01b815260040161046191815260200190565b602060405180830381865afa15801561047e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a29190611780565b9050336001600160a01b038216146104ea57604051632a48cd0560e01b81523360048201526001600160a01b0382166024820152604481018490526064015b60405180910390fd5b5060006002816105006060870160408801611680565b6001600160a01b03168152602080820192909252604090810160009081208784013582529092529020905061054461053d368690038601866117d9565b60e0902090565b8154146105665783604051635b36718360e11b81526004016104e19190611890565b600083815260028201602052604090205460ff16156105a55760405163671e430960e01b815260208501356004820152602481018490526044016104e1565b600083815260028201602052604090819020805460ff191660011790556105f5906105d69060608701908701611680565b6105e660c0870160a08801611931565b6001600160801b031685610b42565b60018201549092506001600160801b0390811690831681106106175782610619565b805b92506106258382611962565b6001830180546001600160801b0319166001600160801b03929092169190911790556106776106576020870187611989565b61066760a0880160808901611680565b33866001600160801b0316610fcc565b33846106896060880160408901611680565b6001600160a01b03167f1ef0986161a82a71426dec04dd3ef55fbf8e44e3cfebccb087acb2f97839c05d6106c060208a018a611989565b6106d060a08b0160808c01611680565b886040516106e0939291906119a4565b60405180910390a4505092915050565b60005b8381101561074d5761073d858583818110610710576107106119da565b905060e00201848484818110610728576107286119da565b90506020020160208101906102629190611680565b610746816119f0565b90506106f3565b5050505050565b6001600160a01b0382166000908152600260209081526040808320848452909152902060010154600160801b900460ff165b92915050565b604051635c9fcd8560e11b8152600b60048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b93f9b0a90602401602060405180830381865afa1580156107f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108189190611780565b9050336001600160a01b038216146108545760405163520b6b7560e01b81523360048201526001600160a01b03821660248201526044016104e1565b507f000000000000000000000000000000000000000000000000000000000000000064ffffffffff1642111561089d5760405163024780c760e11b815260040160405180910390fd5b600080846001600160a01b031684846040516108ba929190611a09565b600060405180830381855af49150503d80600081146108f5576040519150601f19603f3d011682016040523d82523d6000602084013e6108fa565b606091505b50915091508161090d5761090d81611086565b7f14558cdd2442ce65f94cbb821f6ab6b96098fb84a9b0e73fb770ecf12402823c85858560405161094093929190611a19565b60405180910390a15050505050565b60006002816109646060860160408701611680565b6001600160a01b0316815260208082019290925260409081016000908120868401358252909252902090506109a161053d368590038501856117d9565b8154146109c35782604051635b36718360e11b81526004016104e19190611890565b336109d46080850160608601611680565b6001600160a01b031614610a1f57336109f36080850160608601611680565b6040516316fcee0760e31b81526001600160a01b039283166004820152911660248201526044016104e1565b6001810154600160801b900460ff1615610a52576040516308a6347360e11b8152602084013560048201526024016104e1565b60018101805460ff60801b1916600160801b179055610aa6610a776020850185611989565b610a8760a0860160808701611680565b84610a9860e0880160c08901611931565b6001600160801b0316610fcc565b610ab66080840160608501611680565b6001600160a01b0316610acf6060850160408601611680565b6001600160a01b03167f9ee811b8d470c07207b34bef36a0706a357a2e82032798c9bf96dd3d5b7f637c610b066020870187611989565b610b1660a0880160808901611680565b610b2660e0890160c08a01611931565b604051610b35939291906119a4565b60405180910390a3505050565b6000610419670de0b6b3a764000084866001600160a01b03166378cfabac866040518263ffffffff1660e01b8152600401610b7f91815260200190565b602060405180830381865afa158015610b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190611a59565b610bca9190611a72565b610bdc90670de0b6b3a763ffff611a89565b610be69190611ab2565b61108e565b610bf36112ea565b6040805160c0810182526001600160a01b03868116825260016020830152871681830181905291516370a0823160e01b8152306004820152610c9f9260608301916370a0823190602401602060405180830381865afa158015610c5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7e9190611a59565b8152602001856001600160a01b031681526020018461ffff16815250610d76565b95945050505050565b60608367ffffffffffffffff811115610cc357610cc361179d565b604051908082528060200260200182016040528015610cec578160200160208202803683370190505b50905060005b84811015610d6d57610d33868683818110610d0f57610d0f6119da565b905060e00201858584818110610d2757610d276119da565b90506020020135610421565b828281518110610d4557610d456119da565b6001600160801b0390921660209283029190910190910152610d66816119f0565b9050610cf2565b50949350505050565b610d7e6112ea565b6127108260a0015161ffff161115610db55760a0820151604051631c5d694760e21b815261ffff90911660048201526024016104e1565b600080610dca846020015185604001516110bf565b6000818152600160205260409020546060860151919250610def91610be69190611ac6565b9150816001600160801b0316600003610e265760405163971d978d60e01b81526001600160801b03831660048201526024016104e1565b606084015160009182526001602052604082205560a084015161271090610e519061ffff1684611ad9565b610e5b9190611b04565b90506000610e698284611962565b90506040518060e0016040528086602001516001811115610e8c57610e8c6113a9565b815286516001600160a01b03166000908152602081815260408220805491909301929190610eb9906119f0565b919050819055815260200186600001516001600160a01b0316815260200186608001516001600160a01b0316815260200186604001516001600160a01b03168152602001826001600160801b03168152602001836001600160801b03168152509350610f268460e0902090565b85516001600160a01b0390811660009081526002602081815260408084208a8301805186529083528185208c5187168652938352818520905185529091529182902060010180546001600160801b0319166001600160801b03871617905592909255865191519116907f5e656a37d8709548ee29faf0fcd7bf0f875b4c291ee8e184df9e0de4634bb81390610fbc9087906113e1565b60405180910390a2505050919050565b6000610fd885856110bf565b60008181526001602052604081205491925090610ff6908490611ac6565b6000838152600160205260408120600019905590915086600181111561101e5761101e6113a9565b0361103b576110366001600160a01b03851684611124565b611070565b600186600181111561104f5761104f6113a9565b1461105c5761105c611b2a565b6110706001600160a01b03861685856111b0565b6000918252600160205260409091205550505050565b805160208201fd5b60006001600160801b038211156110bb57604051632dc9adf360e01b8152600481018390526024016104e1565b5090565b6000808360018111156110d4576110d46113a9565b036110f4575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee610786565b6001836001811115611108576111086113a9565b1461111557611115611b2a565b506001600160a01b0316919050565b80600003611130575050565b600080836001600160a01b03168360405160006040518083038185875af1925050503d806000811461117e576040519150601f19603f3d011682016040523d82523d6000602084013e611183565b606091505b5091509150816111aa57838160405163354db69760e01b81526004016104e1929190611b64565b50505050565b6040516001600160a01b03838116602483015260448201839052600091829186169060640160408051601f198184030181529181526020820180516001600160e01b031663a9059cbb60e01b1790525161120a9190611ba6565b6000604051808303816000865af19150503d8060008114611247576040519150601f19603f3d011682016040523d82523d6000602084013e61124c565b606091505b509150915081156112b757805160000361129757843b600081900361128f57604051639fe23a3960e01b81526001600160a01b03871660048201526024016104e1565b505050505050565b808060200190518101906112ab9190611bc2565b156112b7575050505050565b604051631702a98760e11b81526001600160a01b03808716600483015285166024820152604481018490526064016104e1565b6040805160e08101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b6001600160a01b038116811461133d57600080fd5b50565b803561134b81611328565b919050565b803561ffff8116811461134b57600080fd5b60008060006060848603121561137757600080fd5b833561138281611328565b9250602084013561139281611328565b91506113a060408501611350565b90509250925092565b634e487b7160e01b600052602160045260246000fd5b600281106113dd57634e487b7160e01b600052602160045260246000fd5b9052565b600060e0820190506113f48284516113bf565b60208301516020830152604083015160018060a01b038082166040850152806060860151166060850152806080860151166080850152505060a08301516001600160801b0380821660a08501528060c08601511660c0850152505092915050565b600060e0828403121561146757600080fd5b50919050565b600080610100838503121561148157600080fd5b61148b8484611455565b9460e0939093013593505050565b60008083601f8401126114ab57600080fd5b50813567ffffffffffffffff8111156114c357600080fd5b60208301915083602060e0830285010111156114de57600080fd5b9250929050565b60008083601f8401126114f757600080fd5b50813567ffffffffffffffff81111561150f57600080fd5b6020830191508360208260051b85010111156114de57600080fd5b6000806000806040858703121561154057600080fd5b843567ffffffffffffffff8082111561155857600080fd5b61156488838901611499565b9096509450602087013591508082111561157d57600080fd5b5061158a878288016114e5565b95989497509550505050565b600080604083850312156115a957600080fd5b82356115b481611328565b946020939093013593505050565b6000806000604084860312156115d757600080fd5b83356115e281611328565b9250602084013567ffffffffffffffff808211156115ff57600080fd5b818601915086601f83011261161357600080fd5b81358181111561162257600080fd5b87602082850101111561163457600080fd5b6020830194508093505050509250925092565b600080610100838503121561165b57600080fd5b6116658484611455565b915060e083013561167581611328565b809150509250929050565b60006020828403121561169257600080fd5b813561169d81611328565b9392505050565b6000806000606084860312156116b957600080fd5b83356116c481611328565b95602085013595506040909401359392505050565b600080600080608085870312156116ef57600080fd5b84356116fa81611328565b9350602085013561170a81611328565b9250604085013561171a81611328565b915061172860608601611350565b905092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156117745783516001600160801b03168352928401929184019160010161174f565b50909695505050505050565b60006020828403121561179257600080fd5b815161169d81611328565b634e487b7160e01b600052604160045260246000fd5b80356002811061134b57600080fd5b80356001600160801b038116811461134b57600080fd5b600060e082840312156117eb57600080fd5b60405160e0810181811067ffffffffffffffff8211171561181c57634e487b7160e01b600052604160045260246000fd5b604052611828836117b3565b81526020830135602082015261184060408401611340565b604082015261185160608401611340565b606082015261186260808401611340565b608082015261187360a084016117c2565b60a082015261188460c084016117c2565b60c08201529392505050565b60e081016118a6826118a1856117b3565b6113bf565b6020830135602083015260408301356118be81611328565b6001600160a01b0390811660408401526060840135906118dd82611328565b90811660608401526080840135906118f482611328565b16608083015261190660a084016117c2565b6001600160801b0380821660a08501528061192360c087016117c2565b1660c0850152505092915050565b60006020828403121561194357600080fd5b61169d826117c2565b634e487b7160e01b600052601160045260246000fd5b6001600160801b038281168282160390808211156119825761198261194c565b5092915050565b60006020828403121561199b57600080fd5b61169d826117b3565b606081016119b282866113bf565b6001600160a01b039390931660208201526001600160801b0391909116604090910152919050565b634e487b7160e01b600052603260045260246000fd5b600060018201611a0257611a0261194c565b5060010190565b8183823760009101908152919050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215611a6b57600080fd5b5051919050565b80820281158282048414176107865761078661194c565b808201808211156107865761078661194c565b634e487b7160e01b600052601260045260246000fd5b600082611ac157611ac1611a9c565b500490565b818103818111156107865761078661194c565b6001600160801b03818116838216028082169190828114611afc57611afc61194c565b505092915050565b60006001600160801b0380841680611b1e57611b1e611a9c565b92169190910492915050565b634e487b7160e01b600052600160045260246000fd5b60005b83811015611b5b578181015183820152602001611b43565b50506000910152565b60018060a01b03831681526040602082015260008251806040840152611b91816060850160208701611b40565b601f01601f1916919091016060019392505050565b60008251611bb8818460208701611b40565b9190910192915050565b600060208284031215611bd457600080fd5b8151801515811461169d57600080fdfea2646970667358221220ef53ba30b91c19fa5ea00cbb4add911660b671fd6d79382cd2826ffdee78fc0764736f6c634300081100330000000000000000000000001ca20040ce6ad406bc2a6c89976388829e7fbade00000000000000000000000000000000000000000000000000000000654edef3

Deployed Bytecode

0x6080604052600436106100dd5760003560e01c8063a73bf89e1161007f578063e3a7ef5511610059578063e3a7ef55146102f1578063e81140ad14610342578063eedaf00d14610362578063ff7c0eea1461038257600080fd5b8063a73bf89e14610247578063bd71711114610267578063e0af030c146102a257600080fd5b806352800e82116100bb57806352800e821461019d57806357f72496146101d55780636984c669146101f7578063a0321a531461022757600080fd5b8063074ae6f1146100e25780633a32e54e14610131578063476f512514610151575b600080fd5b3480156100ee57600080fd5b506101167f00000000000000000000000000000000000000000000000000000000654edef381565b60405164ffffffffff90911681526020015b60405180910390f35b61014461013f366004611362565b6103af565b60405161012891906113e1565b34801561015d57600080fd5b506101857f0000000000000000000000001ca20040ce6ad406bc2a6c89976388829e7fbade81565b6040516001600160a01b039091168152602001610128565b3480156101a957600080fd5b506101bd6101b836600461146d565b610421565b6040516001600160801b039091168152602001610128565b3480156101e157600080fd5b506101f56101f036600461152a565b6106f0565b005b34801561020357600080fd5b50610217610212366004611596565b610754565b6040519015158152602001610128565b34801561023357600080fd5b506101f56102423660046115c2565b61078c565b34801561025357600080fd5b506101f5610262366004611647565b61094f565b34801561027357600080fd5b50610294610282366004611680565b60006020819052908152604090205481565b604051908152602001610128565b3480156102ae57600080fd5b506101bd6102bd366004611596565b6001600160a01b0391909116600090815260026020908152604080832093835292905220600101546001600160801b031690565b3480156102fd57600080fd5b5061021761030c3660046116a4565b6001600160a01b039290921660009081526002602081815260408084209584529481528483209383529201909152205460ff1690565b34801561034e57600080fd5b506101bd61035d3660046116a4565b610b42565b34801561036e57600080fd5b5061014461037d3660046116d9565b610beb565b34801561038e57600080fd5b506103a261039d36600461152a565b610ca8565b6040516101289190611733565b6103b76112ea565b6040805160c081019091526001600160a01b038516815261041990602081016000815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60208201524760408201526001600160a01b038616606082015261ffff8516608090910152610d76565b949350505050565b6000806104346060850160408601611680565b6001600160a01b0316636352211e846040518263ffffffff1660e01b815260040161046191815260200190565b602060405180830381865afa15801561047e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a29190611780565b9050336001600160a01b038216146104ea57604051632a48cd0560e01b81523360048201526001600160a01b0382166024820152604481018490526064015b60405180910390fd5b5060006002816105006060870160408801611680565b6001600160a01b03168152602080820192909252604090810160009081208784013582529092529020905061054461053d368690038601866117d9565b60e0902090565b8154146105665783604051635b36718360e11b81526004016104e19190611890565b600083815260028201602052604090205460ff16156105a55760405163671e430960e01b815260208501356004820152602481018490526044016104e1565b600083815260028201602052604090819020805460ff191660011790556105f5906105d69060608701908701611680565b6105e660c0870160a08801611931565b6001600160801b031685610b42565b60018201549092506001600160801b0390811690831681106106175782610619565b805b92506106258382611962565b6001830180546001600160801b0319166001600160801b03929092169190911790556106776106576020870187611989565b61066760a0880160808901611680565b33866001600160801b0316610fcc565b33846106896060880160408901611680565b6001600160a01b03167f1ef0986161a82a71426dec04dd3ef55fbf8e44e3cfebccb087acb2f97839c05d6106c060208a018a611989565b6106d060a08b0160808c01611680565b886040516106e0939291906119a4565b60405180910390a4505092915050565b60005b8381101561074d5761073d858583818110610710576107106119da565b905060e00201848484818110610728576107286119da565b90506020020160208101906102629190611680565b610746816119f0565b90506106f3565b5050505050565b6001600160a01b0382166000908152600260209081526040808320848452909152902060010154600160801b900460ff165b92915050565b604051635c9fcd8560e11b8152600b60048201526000907f0000000000000000000000001ca20040ce6ad406bc2a6c89976388829e7fbade6001600160a01b03169063b93f9b0a90602401602060405180830381865afa1580156107f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108189190611780565b9050336001600160a01b038216146108545760405163520b6b7560e01b81523360048201526001600160a01b03821660248201526044016104e1565b507f00000000000000000000000000000000000000000000000000000000654edef364ffffffffff1642111561089d5760405163024780c760e11b815260040160405180910390fd5b600080846001600160a01b031684846040516108ba929190611a09565b600060405180830381855af49150503d80600081146108f5576040519150601f19603f3d011682016040523d82523d6000602084013e6108fa565b606091505b50915091508161090d5761090d81611086565b7f14558cdd2442ce65f94cbb821f6ab6b96098fb84a9b0e73fb770ecf12402823c85858560405161094093929190611a19565b60405180910390a15050505050565b60006002816109646060860160408701611680565b6001600160a01b0316815260208082019290925260409081016000908120868401358252909252902090506109a161053d368590038501856117d9565b8154146109c35782604051635b36718360e11b81526004016104e19190611890565b336109d46080850160608601611680565b6001600160a01b031614610a1f57336109f36080850160608601611680565b6040516316fcee0760e31b81526001600160a01b039283166004820152911660248201526044016104e1565b6001810154600160801b900460ff1615610a52576040516308a6347360e11b8152602084013560048201526024016104e1565b60018101805460ff60801b1916600160801b179055610aa6610a776020850185611989565b610a8760a0860160808701611680565b84610a9860e0880160c08901611931565b6001600160801b0316610fcc565b610ab66080840160608501611680565b6001600160a01b0316610acf6060850160408601611680565b6001600160a01b03167f9ee811b8d470c07207b34bef36a0706a357a2e82032798c9bf96dd3d5b7f637c610b066020870187611989565b610b1660a0880160808901611680565b610b2660e0890160c08a01611931565b604051610b35939291906119a4565b60405180910390a3505050565b6000610419670de0b6b3a764000084866001600160a01b03166378cfabac866040518263ffffffff1660e01b8152600401610b7f91815260200190565b602060405180830381865afa158015610b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190611a59565b610bca9190611a72565b610bdc90670de0b6b3a763ffff611a89565b610be69190611ab2565b61108e565b610bf36112ea565b6040805160c0810182526001600160a01b03868116825260016020830152871681830181905291516370a0823160e01b8152306004820152610c9f9260608301916370a0823190602401602060405180830381865afa158015610c5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7e9190611a59565b8152602001856001600160a01b031681526020018461ffff16815250610d76565b95945050505050565b60608367ffffffffffffffff811115610cc357610cc361179d565b604051908082528060200260200182016040528015610cec578160200160208202803683370190505b50905060005b84811015610d6d57610d33868683818110610d0f57610d0f6119da565b905060e00201858584818110610d2757610d276119da565b90506020020135610421565b828281518110610d4557610d456119da565b6001600160801b0390921660209283029190910190910152610d66816119f0565b9050610cf2565b50949350505050565b610d7e6112ea565b6127108260a0015161ffff161115610db55760a0820151604051631c5d694760e21b815261ffff90911660048201526024016104e1565b600080610dca846020015185604001516110bf565b6000818152600160205260409020546060860151919250610def91610be69190611ac6565b9150816001600160801b0316600003610e265760405163971d978d60e01b81526001600160801b03831660048201526024016104e1565b606084015160009182526001602052604082205560a084015161271090610e519061ffff1684611ad9565b610e5b9190611b04565b90506000610e698284611962565b90506040518060e0016040528086602001516001811115610e8c57610e8c6113a9565b815286516001600160a01b03166000908152602081815260408220805491909301929190610eb9906119f0565b919050819055815260200186600001516001600160a01b0316815260200186608001516001600160a01b0316815260200186604001516001600160a01b03168152602001826001600160801b03168152602001836001600160801b03168152509350610f268460e0902090565b85516001600160a01b0390811660009081526002602081815260408084208a8301805186529083528185208c5187168652938352818520905185529091529182902060010180546001600160801b0319166001600160801b03871617905592909255865191519116907f5e656a37d8709548ee29faf0fcd7bf0f875b4c291ee8e184df9e0de4634bb81390610fbc9087906113e1565b60405180910390a2505050919050565b6000610fd885856110bf565b60008181526001602052604081205491925090610ff6908490611ac6565b6000838152600160205260408120600019905590915086600181111561101e5761101e6113a9565b0361103b576110366001600160a01b03851684611124565b611070565b600186600181111561104f5761104f6113a9565b1461105c5761105c611b2a565b6110706001600160a01b03861685856111b0565b6000918252600160205260409091205550505050565b805160208201fd5b60006001600160801b038211156110bb57604051632dc9adf360e01b8152600481018390526024016104e1565b5090565b6000808360018111156110d4576110d46113a9565b036110f4575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee610786565b6001836001811115611108576111086113a9565b1461111557611115611b2a565b506001600160a01b0316919050565b80600003611130575050565b600080836001600160a01b03168360405160006040518083038185875af1925050503d806000811461117e576040519150601f19603f3d011682016040523d82523d6000602084013e611183565b606091505b5091509150816111aa57838160405163354db69760e01b81526004016104e1929190611b64565b50505050565b6040516001600160a01b03838116602483015260448201839052600091829186169060640160408051601f198184030181529181526020820180516001600160e01b031663a9059cbb60e01b1790525161120a9190611ba6565b6000604051808303816000865af19150503d8060008114611247576040519150601f19603f3d011682016040523d82523d6000602084013e61124c565b606091505b509150915081156112b757805160000361129757843b600081900361128f57604051639fe23a3960e01b81526001600160a01b03871660048201526024016104e1565b505050505050565b808060200190518101906112ab9190611bc2565b156112b7575050505050565b604051631702a98760e11b81526001600160a01b03808716600483015285166024820152604481018490526064016104e1565b6040805160e08101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b6001600160a01b038116811461133d57600080fd5b50565b803561134b81611328565b919050565b803561ffff8116811461134b57600080fd5b60008060006060848603121561137757600080fd5b833561138281611328565b9250602084013561139281611328565b91506113a060408501611350565b90509250925092565b634e487b7160e01b600052602160045260246000fd5b600281106113dd57634e487b7160e01b600052602160045260246000fd5b9052565b600060e0820190506113f48284516113bf565b60208301516020830152604083015160018060a01b038082166040850152806060860151166060850152806080860151166080850152505060a08301516001600160801b0380821660a08501528060c08601511660c0850152505092915050565b600060e0828403121561146757600080fd5b50919050565b600080610100838503121561148157600080fd5b61148b8484611455565b9460e0939093013593505050565b60008083601f8401126114ab57600080fd5b50813567ffffffffffffffff8111156114c357600080fd5b60208301915083602060e0830285010111156114de57600080fd5b9250929050565b60008083601f8401126114f757600080fd5b50813567ffffffffffffffff81111561150f57600080fd5b6020830191508360208260051b85010111156114de57600080fd5b6000806000806040858703121561154057600080fd5b843567ffffffffffffffff8082111561155857600080fd5b61156488838901611499565b9096509450602087013591508082111561157d57600080fd5b5061158a878288016114e5565b95989497509550505050565b600080604083850312156115a957600080fd5b82356115b481611328565b946020939093013593505050565b6000806000604084860312156115d757600080fd5b83356115e281611328565b9250602084013567ffffffffffffffff808211156115ff57600080fd5b818601915086601f83011261161357600080fd5b81358181111561162257600080fd5b87602082850101111561163457600080fd5b6020830194508093505050509250925092565b600080610100838503121561165b57600080fd5b6116658484611455565b915060e083013561167581611328565b809150509250929050565b60006020828403121561169257600080fd5b813561169d81611328565b9392505050565b6000806000606084860312156116b957600080fd5b83356116c481611328565b95602085013595506040909401359392505050565b600080600080608085870312156116ef57600080fd5b84356116fa81611328565b9350602085013561170a81611328565b9250604085013561171a81611328565b915061172860608601611350565b905092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156117745783516001600160801b03168352928401929184019160010161174f565b50909695505050505050565b60006020828403121561179257600080fd5b815161169d81611328565b634e487b7160e01b600052604160045260246000fd5b80356002811061134b57600080fd5b80356001600160801b038116811461134b57600080fd5b600060e082840312156117eb57600080fd5b60405160e0810181811067ffffffffffffffff8211171561181c57634e487b7160e01b600052604160045260246000fd5b604052611828836117b3565b81526020830135602082015261184060408401611340565b604082015261185160608401611340565b606082015261186260808401611340565b608082015261187360a084016117c2565b60a082015261188460c084016117c2565b60c08201529392505050565b60e081016118a6826118a1856117b3565b6113bf565b6020830135602083015260408301356118be81611328565b6001600160a01b0390811660408401526060840135906118dd82611328565b90811660608401526080840135906118f482611328565b16608083015261190660a084016117c2565b6001600160801b0380821660a08501528061192360c087016117c2565b1660c0850152505092915050565b60006020828403121561194357600080fd5b61169d826117c2565b634e487b7160e01b600052601160045260246000fd5b6001600160801b038281168282160390808211156119825761198261194c565b5092915050565b60006020828403121561199b57600080fd5b61169d826117b3565b606081016119b282866113bf565b6001600160a01b039390931660208201526001600160801b0391909116604090910152919050565b634e487b7160e01b600052603260045260246000fd5b600060018201611a0257611a0261194c565b5060010190565b8183823760009101908152919050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215611a6b57600080fd5b5051919050565b80820281158282048414176107865761078661194c565b808201808211156107865761078661194c565b634e487b7160e01b600052601260045260246000fd5b600082611ac157611ac1611a9c565b500490565b818103818111156107865761078661194c565b6001600160801b03818116838216028082169190828114611afc57611afc61194c565b505092915050565b60006001600160801b0380841680611b1e57611b1e611a9c565b92169190910492915050565b634e487b7160e01b600052600160045260246000fd5b60005b83811015611b5b578181015183820152602001611b43565b50506000910152565b60018060a01b03831681526040602082015260008251806040840152611b91816060850160208701611b40565b601f01601f1916919091016060019392505050565b60008251611bb8818460208701611b40565b9190910192915050565b600060208284031215611bd457600080fd5b8151801515811461169d57600080fdfea2646970667358221220ef53ba30b91c19fa5ea00cbb4add911660b671fd6d79382cd2826ffdee78fc0764736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000001ca20040ce6ad406bc2a6c89976388829e7fbade00000000000000000000000000000000000000000000000000000000654edef3

-----Decoded View---------------
Arg [0] : globals (address): 0x1cA20040cE6aD406bC2A6c89976388829E7fbAde
Arg [1] : emergencyDisabledTimestamp (uint40): 1699667699

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000001ca20040ce6ad406bc2a6c89976388829e7fbade
Arg [1] : 00000000000000000000000000000000000000000000000000000000654edef3


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.

OSZAR »